From 3f91cb441c41191a62ff500afdc345f1f4b45e31 Mon Sep 17 00:00:00 2001 From: wtt <30461027+wtt40122@users.noreply.github.com> Date: Tue, 11 Jun 2024 17:08:27 +0800 Subject: [PATCH 01/14] refactor: update es and upgrade file (#848) --- .../java/com/xiaomi/mone/es/EsClient.java | 6 +++--- .../com/xiaomi/mone/es/test/EsClientTest.java | 5 +++-- .../mone/es/test/EsProcessorClientTest.java | 7 ++++--- .../java/com/xiaomi/mone/file/ILogFile.java | 7 +++++++ .../java/com/xiaomi/mone/file/LogFile.java | 12 +++++++++++ .../java/com/xiaomi/mone/file/LogFile2.java | 20 ++++++++++++++++--- .../com/xiaomi/mone/file/LogFileTest.java | 6 +++--- 7 files changed, 49 insertions(+), 14 deletions(-) diff --git a/jcommon/es/src/main/java/com/xiaomi/mone/es/EsClient.java b/jcommon/es/src/main/java/com/xiaomi/mone/es/EsClient.java index f557c4d83..e2b145d2f 100644 --- a/jcommon/es/src/main/java/com/xiaomi/mone/es/EsClient.java +++ b/jcommon/es/src/main/java/com/xiaomi/mone/es/EsClient.java @@ -58,8 +58,8 @@ public class EsClient { private static Sniffer sniffer; - private static final int SNIFF_INTERVAL_MILLIS = 30 * 1000; - private static final int SNIFF_AFTER_FAILURE_DELAY_MILLIS = 30 * 1000; + private static final int SNIFF_INTERVAL_MILLIS = 60 * 1000 * 3; + private static final int SNIFF_AFTER_FAILURE_DELAY_MILLIS = 60 * 1000; private static final int MAX_CONN_PER_ROUTE = 500; private static final int MAX_CONN_TOTAL = 500; private static final int SOCKET_TIMEOUT_MS = 10 * 60 * 1000; @@ -196,7 +196,7 @@ private void initializeSniffer() { .setSniffAfterFailureDelayMillis(SNIFF_AFTER_FAILURE_DELAY_MILLIS) .setNodesSniffer(new ElasticsearchNodesSniffer( restClient, - TimeUnit.SECONDS.toMillis(5), + TimeUnit.SECONDS.toMillis(60), ElasticsearchNodesSniffer.Scheme.HTTP)) .build(); sniffOnFailureListener.setSniffer(sniffer); diff --git a/jcommon/es/src/test/java/com/xiaomi/mone/es/test/EsClientTest.java b/jcommon/es/src/test/java/com/xiaomi/mone/es/test/EsClientTest.java index 97ef93055..bc9b5a24f 100644 --- a/jcommon/es/src/test/java/com/xiaomi/mone/es/test/EsClientTest.java +++ b/jcommon/es/src/test/java/com/xiaomi/mone/es/test/EsClientTest.java @@ -226,8 +226,9 @@ public void getClusterHealth() throws IOException { @Test public void queryIndexMetadataTest() throws IOException { - GetMappingsResponse metadata = client.queryIndexMapping("zgq_common_milog_staging_app_private_1"); - System.out.println(String.format("result:%s", gson.toJson(metadata))); + GetMappingsResponse metadata = client.queryIndexMapping("test_scf_log_index"); +// Map mappings = metadata.mappings(); +// System.out.println(String.format("result:%s", gson.toJson(metadata))); } @Test diff --git a/jcommon/es/src/test/java/com/xiaomi/mone/es/test/EsProcessorClientTest.java b/jcommon/es/src/test/java/com/xiaomi/mone/es/test/EsProcessorClientTest.java index 7653a6d56..a6a7fb69b 100644 --- a/jcommon/es/src/test/java/com/xiaomi/mone/es/test/EsProcessorClientTest.java +++ b/jcommon/es/src/test/java/com/xiaomi/mone/es/test/EsProcessorClientTest.java @@ -22,7 +22,7 @@ public void bulkInsert() throws InterruptedException { NacosConfig config = new NacosConfig(); config.setDataId("zzy_new"); - config.init(); +// config.init(); String ip = config.getConfig("es_ip"); String user = config.getConfig("es_user"); @@ -53,13 +53,14 @@ public void afterBulk(long executionId, BulkRequest request, Throwable failure) int count = 0; while (true) { // processor.bulkInsert(indexName, data); - processor.bulkUpsert(indexName, "YpzPE4UBt3Uy5NFQ1V5e", data); + processor.bulkInsert(indexName, data); count++; if (count == n) { break; } } - Thread.sleep(10000l); +// Thread.sleep(10000l); + System.in.read(); }catch (Exception e){ e.printStackTrace(); } diff --git a/jcommon/file/src/main/java/com/xiaomi/mone/file/ILogFile.java b/jcommon/file/src/main/java/com/xiaomi/mone/file/ILogFile.java index 0a898721e..f78f883e6 100644 --- a/jcommon/file/src/main/java/com/xiaomi/mone/file/ILogFile.java +++ b/jcommon/file/src/main/java/com/xiaomi/mone/file/ILogFile.java @@ -16,5 +16,12 @@ public interface ILogFile { void initLogFile(String file, ReadListener listener, long pointer, long lineNumber); + /** + * It only needs to be called when an exception occurs and can only be called externally. + */ + void setExceptionFinish(); + + boolean getExceptionFinish(); + } diff --git a/jcommon/file/src/main/java/com/xiaomi/mone/file/LogFile.java b/jcommon/file/src/main/java/com/xiaomi/mone/file/LogFile.java index 5f8b82b61..71654948e 100644 --- a/jcommon/file/src/main/java/com/xiaomi/mone/file/LogFile.java +++ b/jcommon/file/src/main/java/com/xiaomi/mone/file/LogFile.java @@ -35,6 +35,8 @@ public class LogFile implements ILogFile { @Setter private volatile boolean reFresh; + private volatile boolean exceptionFinish; + @Getter private int beforePointerHashCode; @@ -171,6 +173,16 @@ public void initLogFile(String file, ReadListener listener, long pointer, long l this.lineNumber = lineNumber; } + @Override + public void setExceptionFinish() { + exceptionFinish = true; + } + + @Override + public boolean getExceptionFinish() { + return exceptionFinish; + } + private String lineCutOff(String line) { if (null != line) { //todo 大行文件先临时截断 diff --git a/jcommon/file/src/main/java/com/xiaomi/mone/file/LogFile2.java b/jcommon/file/src/main/java/com/xiaomi/mone/file/LogFile2.java index 27a921211..e77743c3a 100644 --- a/jcommon/file/src/main/java/com/xiaomi/mone/file/LogFile2.java +++ b/jcommon/file/src/main/java/com/xiaomi/mone/file/LogFile2.java @@ -42,6 +42,8 @@ public class LogFile2 implements ILogFile { @Setter private volatile boolean reFresh; + private volatile boolean exceptionFinish; + @Getter private int beforePointerHashCode; @@ -110,12 +112,13 @@ private void open() { } } + @Override public void readLine() throws IOException { while (true) { open(); //兼容文件切换时,缓存的pointer try { - log.info("open file:{},pointer:{}", file, this.pointer); + log.info("open file:{},pointer:{},lineNumber:{},", file, this.pointer, this.lineNumber); if (pointer > raf.length()) { pointer = 0; lineNumber = 0; @@ -123,7 +126,7 @@ public void readLine() throws IOException { } catch (Exception e) { log.error("file.length() IOException, file:{}", this.file, e); } - log.info("rel open file:{},pointer:{}", file, this.pointer); + log.info("rel open file:{},pointer:{},lineNumber:{}", file, this.pointer, this.lineNumber); raf.seek(pointer); while (true) { @@ -166,6 +169,7 @@ public void readLine() throws IOException { } if (listener.isBreak(line)) { + log.info("isBreak:{},pointer:{},lineNumber:{},fileKey:{}", this.file, this.pointer, this.lineNumber, this.fileKey); stop = true; break; } @@ -193,7 +197,7 @@ public void readLine() throws IOException { } raf.close(); if (stop) { - log.info("stop:{},pointer:{},fileKey:{}", this.file, this.pointer, this.fileKey); + log.info("stop:{},pointer:{},lineNumber:{},fileKey:{}", this.file, this.pointer, this.lineNumber, this.fileKey); FileInfoCache.ins().put(this.fileKey.toString(), FileInfo.builder().pointer(this.pointer).fileName(this.file).build()); break; } @@ -209,6 +213,16 @@ public void initLogFile(String file, ReadListener listener, long pointer, long l this.lineNumber = lineNumber; } + @Override + public void setExceptionFinish() { + exceptionFinish = true; + } + + @Override + public boolean getExceptionFinish() { + return exceptionFinish; + } + private String lineCutOff(String line) { if (null != line) { //todo 大行文件先临时截断 diff --git a/jcommon/file/src/test/java/com/xiaomi/mone/file/LogFileTest.java b/jcommon/file/src/test/java/com/xiaomi/mone/file/LogFileTest.java index 363f59624..8644d3e01 100644 --- a/jcommon/file/src/test/java/com/xiaomi/mone/file/LogFileTest.java +++ b/jcommon/file/src/test/java/com/xiaomi/mone/file/LogFileTest.java @@ -74,12 +74,12 @@ public void testLogFileMonitor() { monitor.setListener(new DefaultMonitorListener(monitor, readEvent -> { System.out.println(readEvent.getReadResult().getLines()); })); - String fileName = "/home/work/log/test/provider/server.log.*"; + String fileName = "/home/work/log/file.log.*"; Pattern pattern = Pattern.compile(fileName); - monitor.reg("/home/work/log/test/provider/", it -> { + monitor.reg("/home/work/log", it -> { boolean matches = pattern.matcher(it).matches(); log.info("file:{},matches:{}", it, matches); - return matches; + return true; }); log.info("reg finish"); System.in.read(); From 16f5df8cad3cd01e33422e94dc348a3e342383f5 Mon Sep 17 00:00:00 2001 From: zhangping17 Date: Fri, 21 Jun 2024 20:20:04 +0800 Subject: [PATCH 02/14] claude3.5 --- .../java/run/mone/ai/google/CloudeClient.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java b/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java index 63f71c457..67e929be4 100644 --- a/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java +++ b/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java @@ -84,4 +84,35 @@ public ResponsePayload call(String token, RequestPayload requestPayload) { return null; } + public ResponsePayload call(String url ,String token, RequestPayload requestPayload) { + OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.MINUTES).build(); + MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); + RequestBody body = RequestBody.create(mediaType, new Gson().toJson(requestPayload)); + Request request = new Request.Builder() + .url(url) + .post(body) + .addHeader("Authorization", "Bearer " + token) + .addHeader("Content-Type", "application/json; charset=utf-8") + .build(); + + try (Response response = client.newCall(request).execute()) { + if (response.code() == 429) { + ResponsePayload res = new ResponsePayload(); + Content content = new Content(); + content.setText(gson.toJson(ImmutableMap.of("message", "被claude3限流了", "code", "429"))); + log.info("claude res:{}", content.getText()); + res.setContent(Lists.newArrayList(content)); + return res; + } + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + // Handle the response + String res = response.body().string(); + log.info("claude3 res:{}", res); + return new Gson().fromJson(res, ResponsePayload.class); + } catch (Throwable e) { + log.error(e.getMessage(), e); + } + return null; + } + } From 9e990c82ab3f2a8ebf1b0abd3012cee7a5380cfb Mon Sep 17 00:00:00 2001 From: zhangping17 Date: Thu, 27 Jun 2024 11:36:48 +0800 Subject: [PATCH 03/14] claude3.5 --- .../google/src/main/java/run/mone/ai/google/CloudeClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java b/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java index 67e929be4..0c3722ff7 100644 --- a/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java +++ b/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java @@ -40,9 +40,9 @@ public class CloudeClient { @SneakyThrows - public String token() { + public String token(String model) { GoogleCredentials credentials = GoogleCredentials.fromStream( - new FileInputStream("/tmp/key.json")) + new FileInputStream("/tmp/key-"+model+".json")) .createScoped(Collections.singleton("https://" + googleUrl + "/auth/cloud-platform")); // Use the credentials to authenticate and generate an access token credentials.refreshIfExpired(); From 816397e6f5cf0e4887d6f515a2a05e91e102862f Mon Sep 17 00:00:00 2001 From: zhangzhiyong Date: Tue, 2 Jul 2024 10:03:28 +0800 Subject: [PATCH 04/14] [enhancement] JCommon MongoDB supports pagination queries #851 --- jcommon/ai/bytedance/pom.xml | 7 +++ .../run/mone/ai/bytedance/DoubaoClient.java | 56 +++++++++++++++++++ .../src/main/java/run/mone/auth/AuthAop.java | 5 ++ .../src/main/java/run/mone/bo/User.java | 6 +- .../java/run/mone/service/MongoService.java | 22 ++++++++ .../youpin/docean/test/HttpServerTest.java | 3 +- jcommon/pom.xml | 30 +++++----- 7 files changed, 112 insertions(+), 17 deletions(-) create mode 100644 jcommon/ai/bytedance/src/main/java/run/mone/ai/bytedance/DoubaoClient.java diff --git a/jcommon/ai/bytedance/pom.xml b/jcommon/ai/bytedance/pom.xml index bbadac9dd..b19d7e7e2 100644 --- a/jcommon/ai/bytedance/pom.xml +++ b/jcommon/ai/bytedance/pom.xml @@ -29,6 +29,13 @@ jackson-databind 2.12.4 + + + com.squareup.okhttp3 + okhttp + 4.10.0 + + diff --git a/jcommon/ai/bytedance/src/main/java/run/mone/ai/bytedance/DoubaoClient.java b/jcommon/ai/bytedance/src/main/java/run/mone/ai/bytedance/DoubaoClient.java new file mode 100644 index 000000000..94808fb5f --- /dev/null +++ b/jcommon/ai/bytedance/src/main/java/run/mone/ai/bytedance/DoubaoClient.java @@ -0,0 +1,56 @@ +package run.mone.ai.bytedance; + + +import okhttp3.*; + +/** + * @author goodjava@qq.com + * @date 2024/5/18 17:20 + */ +public class DoubaoClient { + + private static String ARK_API_KEY = ""; + + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient(); + String json = "{\n" + + " \"model\": \"\",\n" + + " \"messages\": [\n" + + " {\n" + + " \"role\": \"system\",\n" + + " \"content\": \"You are a helpful assistant.\"\n" + + " },\n" + + " {\n" + + " \"role\": \"user\",\n" + + " \"content\": \"Hello!\"\n" + + " }\n" + + " ],\n" + + " \"stream\": false\n" + + "}"; + + MediaType JSON = MediaType.get("application/json; charset=utf-8"); + RequestBody body = RequestBody.create(json, JSON); + + Request request = new Request.Builder() + .url("") + .addHeader("Content-Type", "application/json") + .addHeader("Authorization", "Bearer " + ARK_API_KEY) // 确保你已经设置了 ARK_API_KEY 变量 + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + // 处理响应 + if (response.isSuccessful()) { + String responseBody = response.body().string(); + System.out.println(responseBody); + } else { + System.out.println(response); + } + } catch (Exception e) { + e.printStackTrace(); + } + + + } + +} diff --git a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/AuthAop.java b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/AuthAop.java index f9ea28bfa..ad8252e42 100644 --- a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/AuthAop.java +++ b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/AuthAop.java @@ -68,6 +68,11 @@ public void before(ProceedingJoinPoint point) { } } + //没有就当普通用户处理 + if (null == user.getRole()) { + user.setRole("user"); + } + //必须有后台管理权限 if (role.equals("admin")) { if (null == user || !user.getRole().equals("admin")) { diff --git a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/bo/User.java b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/bo/User.java index 01f224d39..0480cfc6c 100644 --- a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/bo/User.java +++ b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/bo/User.java @@ -7,6 +7,8 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Map; + /** * 用户 * @@ -17,7 +19,7 @@ @AllArgsConstructor @NoArgsConstructor @Entity("user") -public class User implements MongoBo{ +public class User implements MongoBo { @Id private String id; @@ -57,6 +59,8 @@ public class User implements MongoBo{ private String token; + private Map meta; + public User(String username, String password) { this.username = username; this.password = password; diff --git a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java index 7b0171630..8b5726413 100644 --- a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java +++ b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java @@ -3,6 +3,7 @@ import com.xiaomi.youpin.docean.anno.Service; import dev.morphia.Datastore; import dev.morphia.UpdateOptions; +import dev.morphia.query.FindOptions; import dev.morphia.query.filters.Filter; import dev.morphia.query.filters.Filters; import dev.morphia.query.updates.UpdateOperator; @@ -65,6 +66,27 @@ public List findAll(Filter filter) { return datastore.find(this.clazz).filter(filter).iterator().toList(); } + public List findAll() { + return datastore.find(this.clazz).iterator().toList(); + } + + //实现分页查询(class) + public List findWithPagination(Filter filter, int page, int size) { + FindOptions options = new FindOptions() + .skip((page - 1) * size) + .limit(size); + return datastore.find(this.clazz) + .filter(filter) + .iterator(options) + .toList(); + } + + //查询总页数(class) + public long getTotalPages(Filter filter, int pageSize) { + long totalRecords = datastore.find(this.clazz).filter(filter).count(); + return (totalRecords + pageSize - 1) / pageSize; + } + public boolean delete(T t) { datastore.delete(t); return true; diff --git a/jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/HttpServerTest.java b/jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/HttpServerTest.java index bce62cebd..33ede037e 100644 --- a/jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/HttpServerTest.java +++ b/jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/HttpServerTest.java @@ -116,7 +116,8 @@ public void testWebSocketServer() { @Test public void testWebSocketClient() { OkHttpClient client = new OkHttpClient(); - Request request = new Request.Builder().url("ws://127.0.0.1:8899/ws").build(); +// Request request = new Request.Builder().url("ws://127.0.0.1:8899/ws").build(); + Request request = new Request.Builder().url("").build(); WebSocketListener listener = new WebSocketListener() { @Override public void onOpen(WebSocket webSocket, Response response) { diff --git a/jcommon/pom.xml b/jcommon/pom.xml index bd8a0c84c..66ebff815 100644 --- a/jcommon/pom.xml +++ b/jcommon/pom.xml @@ -232,21 +232,21 @@ - - - - - - - - - - - - - - - + + maven-source-plugin + 2.1 + + + compile + + jar + + + + + true + + From 7ab5014b81d11cf766c4bd8aaf75e018a168e327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=BF=97=E5=8B=87?= Date: Tue, 2 Jul 2024 10:10:18 +0800 Subject: [PATCH 05/14] [enhancement] JCommon MongoDB supports pagination queries #851 (#852) --- jcommon/ai/bytedance/pom.xml | 7 +++ .../run/mone/ai/bytedance/DoubaoClient.java | 56 +++++++++++++++++++ .../src/main/java/run/mone/auth/AuthAop.java | 5 ++ .../src/main/java/run/mone/bo/User.java | 6 +- .../java/run/mone/service/MongoService.java | 22 ++++++++ .../youpin/docean/test/HttpServerTest.java | 3 +- jcommon/pom.xml | 30 +++++----- 7 files changed, 112 insertions(+), 17 deletions(-) create mode 100644 jcommon/ai/bytedance/src/main/java/run/mone/ai/bytedance/DoubaoClient.java diff --git a/jcommon/ai/bytedance/pom.xml b/jcommon/ai/bytedance/pom.xml index bbadac9dd..b19d7e7e2 100644 --- a/jcommon/ai/bytedance/pom.xml +++ b/jcommon/ai/bytedance/pom.xml @@ -29,6 +29,13 @@ jackson-databind 2.12.4 + + + com.squareup.okhttp3 + okhttp + 4.10.0 + + diff --git a/jcommon/ai/bytedance/src/main/java/run/mone/ai/bytedance/DoubaoClient.java b/jcommon/ai/bytedance/src/main/java/run/mone/ai/bytedance/DoubaoClient.java new file mode 100644 index 000000000..94808fb5f --- /dev/null +++ b/jcommon/ai/bytedance/src/main/java/run/mone/ai/bytedance/DoubaoClient.java @@ -0,0 +1,56 @@ +package run.mone.ai.bytedance; + + +import okhttp3.*; + +/** + * @author goodjava@qq.com + * @date 2024/5/18 17:20 + */ +public class DoubaoClient { + + private static String ARK_API_KEY = ""; + + public static void main(String[] args) { + OkHttpClient client = new OkHttpClient(); + String json = "{\n" + + " \"model\": \"\",\n" + + " \"messages\": [\n" + + " {\n" + + " \"role\": \"system\",\n" + + " \"content\": \"You are a helpful assistant.\"\n" + + " },\n" + + " {\n" + + " \"role\": \"user\",\n" + + " \"content\": \"Hello!\"\n" + + " }\n" + + " ],\n" + + " \"stream\": false\n" + + "}"; + + MediaType JSON = MediaType.get("application/json; charset=utf-8"); + RequestBody body = RequestBody.create(json, JSON); + + Request request = new Request.Builder() + .url("") + .addHeader("Content-Type", "application/json") + .addHeader("Authorization", "Bearer " + ARK_API_KEY) // 确保你已经设置了 ARK_API_KEY 变量 + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + // 处理响应 + if (response.isSuccessful()) { + String responseBody = response.body().string(); + System.out.println(responseBody); + } else { + System.out.println(response); + } + } catch (Exception e) { + e.printStackTrace(); + } + + + } + +} diff --git a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/AuthAop.java b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/AuthAop.java index f9ea28bfa..ad8252e42 100644 --- a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/AuthAop.java +++ b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/AuthAop.java @@ -68,6 +68,11 @@ public void before(ProceedingJoinPoint point) { } } + //没有就当普通用户处理 + if (null == user.getRole()) { + user.setRole("user"); + } + //必须有后台管理权限 if (role.equals("admin")) { if (null == user || !user.getRole().equals("admin")) { diff --git a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/bo/User.java b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/bo/User.java index 01f224d39..0480cfc6c 100644 --- a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/bo/User.java +++ b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/bo/User.java @@ -7,6 +7,8 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.util.Map; + /** * 用户 * @@ -17,7 +19,7 @@ @AllArgsConstructor @NoArgsConstructor @Entity("user") -public class User implements MongoBo{ +public class User implements MongoBo { @Id private String id; @@ -57,6 +59,8 @@ public class User implements MongoBo{ private String token; + private Map meta; + public User(String username, String password) { this.username = username; this.password = password; diff --git a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java index 7b0171630..8b5726413 100644 --- a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java +++ b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java @@ -3,6 +3,7 @@ import com.xiaomi.youpin.docean.anno.Service; import dev.morphia.Datastore; import dev.morphia.UpdateOptions; +import dev.morphia.query.FindOptions; import dev.morphia.query.filters.Filter; import dev.morphia.query.filters.Filters; import dev.morphia.query.updates.UpdateOperator; @@ -65,6 +66,27 @@ public List findAll(Filter filter) { return datastore.find(this.clazz).filter(filter).iterator().toList(); } + public List findAll() { + return datastore.find(this.clazz).iterator().toList(); + } + + //实现分页查询(class) + public List findWithPagination(Filter filter, int page, int size) { + FindOptions options = new FindOptions() + .skip((page - 1) * size) + .limit(size); + return datastore.find(this.clazz) + .filter(filter) + .iterator(options) + .toList(); + } + + //查询总页数(class) + public long getTotalPages(Filter filter, int pageSize) { + long totalRecords = datastore.find(this.clazz).filter(filter).count(); + return (totalRecords + pageSize - 1) / pageSize; + } + public boolean delete(T t) { datastore.delete(t); return true; diff --git a/jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/HttpServerTest.java b/jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/HttpServerTest.java index bce62cebd..33ede037e 100644 --- a/jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/HttpServerTest.java +++ b/jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/HttpServerTest.java @@ -116,7 +116,8 @@ public void testWebSocketServer() { @Test public void testWebSocketClient() { OkHttpClient client = new OkHttpClient(); - Request request = new Request.Builder().url("ws://127.0.0.1:8899/ws").build(); +// Request request = new Request.Builder().url("ws://127.0.0.1:8899/ws").build(); + Request request = new Request.Builder().url("").build(); WebSocketListener listener = new WebSocketListener() { @Override public void onOpen(WebSocket webSocket, Response response) { diff --git a/jcommon/pom.xml b/jcommon/pom.xml index bd8a0c84c..66ebff815 100644 --- a/jcommon/pom.xml +++ b/jcommon/pom.xml @@ -232,21 +232,21 @@ - - - - - - - - - - - - - - - + + maven-source-plugin + 2.1 + + + compile + + jar + + + + + true + + From beeae95a0ddbd4ef529158dcfb9e4a37995305a9 Mon Sep 17 00:00:00 2001 From: rikaaa0928 Date: Tue, 2 Jul 2024 14:31:10 +0800 Subject: [PATCH 06/14] [enhancement] JCommon MongoDB UserController set default role at login --- .../src/main/java/run/mone/controller/UserController.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/controller/UserController.java b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/controller/UserController.java index bd8ad309d..86de53110 100644 --- a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/controller/UserController.java +++ b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/controller/UserController.java @@ -4,6 +4,7 @@ import com.xiaomi.youpin.docean.anno.ModelAttribute; import com.xiaomi.youpin.docean.anno.RequestMapping; import com.xiaomi.youpin.docean.anno.RequestParam; +import com.xiaomi.youpin.docean.common.StringUtils; import com.xiaomi.youpin.docean.mvc.ContextHolder; import com.xiaomi.youpin.docean.mvc.MvcContext; import run.mone.bo.User; @@ -104,6 +105,9 @@ public String login(User userReq) { return "error"; } user.setPassword(""); + if (StringUtils.isEmpty(user.getRole())) { + user.setRole("user"); + } context.session().setAttribute("user", user); return "ok"; } From b65bb034064cd70a85a0070f2ae9aeb4376a14f3 Mon Sep 17 00:00:00 2001 From: rikaaa0928 <8528731+rikaaa0928@users.noreply.github.com> Date: Tue, 2 Jul 2024 16:18:43 +0800 Subject: [PATCH 07/14] [enhancement] JCommon MongoDB UserController fix default role for annotation (#854) --- .../docean-plugin-mongodb/src/main/java/run/mone/auth/Auth.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/Auth.java b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/Auth.java index 80b0238db..daea12999 100644 --- a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/Auth.java +++ b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/auth/Auth.java @@ -29,5 +29,5 @@ String name() default "name"; - String role() default "admin"; + String role() default "user"; } From afc6ef022fdc6d7b64eddc8f75e3dc6a5a2d939a Mon Sep 17 00:00:00 2001 From: zhangzhiyong Date: Wed, 3 Jul 2024 18:48:46 +0800 Subject: [PATCH 08/14] [enhancement] support Native Return in docean-mvc Module #855 --- .../java/com/xiaomi/youpin/docean/Mvc.java | 23 +++++++++++++++---- .../youpin/docean/anno/RequestMapping.java | 3 +++ .../youpin/docean/mvc/HttpRequestMethod.java | 3 +++ .../xiaomi/youpin/docean/mvc/MvcContext.java | 2 +- .../xiaomi/youpin/docean/mvc/MvcRunnable.java | 1 - 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/Mvc.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/Mvc.java index 7d5f6c201..0a73ec97f 100644 --- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/Mvc.java +++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/Mvc.java @@ -16,6 +16,7 @@ package com.xiaomi.youpin.docean; +import com.google.common.base.Throwables; import com.google.common.collect.Maps; import com.google.gson.Gson; import com.google.gson.JsonElement; @@ -138,6 +139,7 @@ private void registerControllerMethods(Bean bean) { } HttpRequestMethod hrm = new HttpRequestMethod(); hrm.setTimeout(rm.timeout()); + hrm.setOriginalRes(rm.originalRes()); hrm.setPath(path); hrm.setObj(bean.getObj()); hrm.setMethod(m); @@ -252,11 +254,8 @@ public void callMethod(MvcContext context, MvcRequest request, MvcResponse respo return; } // get whether the configuration returns an unwrapped value - boolean needOriginalValue = this.mvcConfig.isResponseOriginalValue(); - if (!needOriginalValue && StringUtils.isNotBlank(this.mvcConfig.getResponseOriginalPath())) { - needOriginalValue = Arrays.stream(mvcConfig.getResponseOriginalPath().split(",")) - .anyMatch(i -> i.equals(method.getPath())); - } + boolean needOriginalValue = isNeedOriginalValue(method); + if (needOriginalValue) { String responseData = data instanceof String ? (String) data : gson.toJson(data); response.writeAndFlush(context, responseData); @@ -269,6 +268,7 @@ public void callMethod(MvcContext context, MvcRequest request, MvcResponse respo context.setResponse(ex); return; } + ex = Throwables.getRootCause(ex); Throwable unwrapThrowable = ExceptionUtil.unwrapThrowable(ex); result.setCode(500); int httpCode = 200; @@ -284,6 +284,19 @@ public void callMethod(MvcContext context, MvcRequest request, MvcResponse respo }); } + private boolean isNeedOriginalValue(HttpRequestMethod method) { + //优先级最高 + if (method.isOriginalRes()) { + return true; + } + boolean needOriginalValue = this.mvcConfig.isResponseOriginalValue(); + if (!needOriginalValue && StringUtils.isNotBlank(this.mvcConfig.getResponseOriginalPath())) { + needOriginalValue = Arrays.stream(mvcConfig.getResponseOriginalPath().split(",")) + .anyMatch(i -> i.equals(method.getPath())); + } + return needOriginalValue; + } + private Object[] getMethodParams(MvcContext context, MvcRequest request, HttpRequestMethod method) { Object[] params = new Object[]{null}; if (context.isWebsocket()) { diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/anno/RequestMapping.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/anno/RequestMapping.java index a1cb37aa1..9b24e7d98 100644 --- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/anno/RequestMapping.java +++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/anno/RequestMapping.java @@ -33,4 +33,7 @@ long timeout() default 2000; + //是否是原始res + boolean originalRes() default false; + } diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/HttpRequestMethod.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/HttpRequestMethod.java index 70756ec32..8faa6bc89 100644 --- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/HttpRequestMethod.java +++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/HttpRequestMethod.java @@ -37,6 +37,9 @@ public class HttpRequestMethod { private long timeout; + //结果不封装 + private boolean originalRes; + private Map genericSuperclassTypeArguments; diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcContext.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcContext.java index d3acec10a..a05a23d17 100644 --- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcContext.java +++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcContext.java @@ -63,7 +63,7 @@ public class MvcContext { private Object response; - private String contentType; + private String contentType = "application/json; charset=utf-8"; /** * rate limited or exceeded quota diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcRunnable.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcRunnable.java index 8e848470c..70242831e 100644 --- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcRunnable.java +++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/MvcRunnable.java @@ -2,7 +2,6 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; -import com.google.gson.JsonParser; import com.xiaomi.youpin.docean.Mvc; import com.xiaomi.youpin.docean.bo.MvcConfig; import com.xiaomi.youpin.docean.common.Cons; From 280045fc4f11adfd9b87f08c6f3a68147372cf8d Mon Sep 17 00:00:00 2001 From: rikaaa0928 <8528731+rikaaa0928@users.noreply.github.com> Date: Thu, 4 Jul 2024 16:57:13 +0800 Subject: [PATCH 09/14] [enhancement] JCommon MongoDB MongoService add option for delete (#857) --- .../src/main/java/run/mone/service/MongoService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java index 8b5726413..315a675ac 100644 --- a/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java +++ b/jcommon/docean-plugin/docean-plugin-mongodb/src/main/java/run/mone/service/MongoService.java @@ -2,6 +2,7 @@ import com.xiaomi.youpin.docean.anno.Service; import dev.morphia.Datastore; +import dev.morphia.DeleteOptions; import dev.morphia.UpdateOptions; import dev.morphia.query.FindOptions; import dev.morphia.query.filters.Filter; @@ -101,6 +102,11 @@ public boolean delete(Filter filter) { return true; } + public boolean delete(Filter filter, DeleteOptions options) { + datastore.find(this.clazz).filter(filter).delete(options); + return true; + } + public boolean update(T t) { t.setUtime(System.currentTimeMillis()); datastore.merge(t); From 35266944b29965dd0d0126c8cdc941722511cf38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=BF=97=E5=8B=87?= Date: Fri, 5 Jul 2024 14:30:44 +0800 Subject: [PATCH 10/14] [enhancement] Enhance Session Expiry Time for Docean (#859) --- .../mvc/session/HttpSessionManager.java | 15 +++++++--- .../xiaomi/youpin/docean/test/MapTest.java | 28 +++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/MapTest.java diff --git a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/HttpSessionManager.java b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/HttpSessionManager.java index 4dc95688c..2c8758044 100644 --- a/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/HttpSessionManager.java +++ b/jcommon/docean/src/main/java/com/xiaomi/youpin/docean/mvc/session/HttpSessionManager.java @@ -46,7 +46,7 @@ public class HttpSessionManager { long now = System.currentTimeMillis(); List ids = SESSION_MAP.values().stream().filter(it -> { DefaultHttpSession hs = (DefaultHttpSession) it; - if (now - hs.getUpdateTime() > TimeUnit.MINUTES.toMillis(10)) { + if (now - hs.getUpdateTime() > TimeUnit.MINUTES.toMillis(60)) { return true; } return false; @@ -82,7 +82,14 @@ public static void invalidate(String sessionId) { } public static HttpSession getSession(String sessionId) { - return SESSION_MAP.get(sessionId); + return SESSION_MAP.compute(sessionId, (k, v) -> { + if (null != v) { + if (v instanceof DefaultHttpSession dhs) { + dhs.setUpdateTime(System.currentTimeMillis()); + } + } + return v; + }); } @@ -105,7 +112,7 @@ public static HttpSession getSession(MvcContext context) { public static void setSessionId(MvcContext context, boolean exists, FullHttpResponse response) { if (!context.getSessionId().equals("")) { - Cookie cookie = new DefaultCookie(HttpSession.SESSIONID,context.getSessionId()); + Cookie cookie = new DefaultCookie(HttpSession.SESSIONID, context.getSessionId()); cookie.setPath("/"); String encodeCookie = ServerCookieEncoder.STRICT.encode(cookie); response.headers().set(HttpHeaderNames.SET_COOKIE, encodeCookie); @@ -113,7 +120,7 @@ public static void setSessionId(MvcContext context, boolean exists, FullHttpResp } if (exists == false) { - Cookie cookie = new DefaultCookie(HttpSession.SESSIONID,HttpSessionManager.createSession()); + Cookie cookie = new DefaultCookie(HttpSession.SESSIONID, HttpSessionManager.createSession()); cookie.setPath("/"); String encodeCookie = ServerCookieEncoder.STRICT.encode(cookie); response.headers().set(HttpHeaderNames.SET_COOKIE, encodeCookie); diff --git a/jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/MapTest.java b/jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/MapTest.java new file mode 100644 index 000000000..66e7b9fe1 --- /dev/null +++ b/jcommon/docean/src/test/java/com/xiaomi/youpin/docean/test/MapTest.java @@ -0,0 +1,28 @@ +package com.xiaomi.youpin.docean.test; + +import com.xiaomi.youpin.docean.common.MutableObject; +import org.junit.Test; + +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author goodjava@qq.com + * @date 2024/7/5 08:18 + */ +public class MapTest { + + @Test + public void testMap() { + MutableObject mo = new MutableObject(); + ConcurrentHashMap map = new ConcurrentHashMap<>(); + mo.setObj("123"); + map.put("aa",mo); + MutableObject e = map.compute("a", (k, v) -> { + if (null != v) { + v.setObj("234"); + } + return v; + }); + System.out.println(e); + } +} From 539bdfc8151054e1738afa47fafd3b8e64427b9c Mon Sep 17 00:00:00 2001 From: HawickMason <1914991129@qq.com> Date: Fri, 12 Jul 2024 16:24:38 +0800 Subject: [PATCH 11/14] feat(codegen): support feature and test and table generation based on template or generator (#862) Co-authored-by: wangyingjie3 --- jcommon/codegen/pom.xml | 17 ++ .../run/mone/ai/codegen/FeatureGenerator.java | 149 ++++++++++++++++++ .../mone/ai/codegen/UnitTestGenerator.java | 12 ++ .../ai/codegen/bo/FeatureGeneratType.java | 39 +++++ .../mone/ai/codegen/bo/FeatureGenerateBo.java | 76 +++++++++ .../mone/ai/codegen/util/TemplateUtils.java | 73 +++++++++ .../src/main/resources/tlp/code_test.txt | 2 + .../src/main/resources/tlp/controller.java | 41 +++++ .../codegen/src/main/resources/tlp/pojo.java | 32 ++++ .../src/main/resources/tlp/service.java | 20 +++ .../codegen/src/main/resources/tlp/test.java | 32 ++++ .../src/main/resources/tlp/transfer.java | 24 +++ .../codegen/src/main/resources/tlp/vo.java | 21 +++ 13 files changed, 538 insertions(+) create mode 100644 jcommon/codegen/src/main/java/run/mone/ai/codegen/FeatureGenerator.java create mode 100644 jcommon/codegen/src/main/java/run/mone/ai/codegen/UnitTestGenerator.java create mode 100644 jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGeneratType.java create mode 100644 jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGenerateBo.java create mode 100644 jcommon/codegen/src/main/java/run/mone/ai/codegen/util/TemplateUtils.java create mode 100644 jcommon/codegen/src/main/resources/tlp/code_test.txt create mode 100644 jcommon/codegen/src/main/resources/tlp/controller.java create mode 100644 jcommon/codegen/src/main/resources/tlp/pojo.java create mode 100644 jcommon/codegen/src/main/resources/tlp/service.java create mode 100644 jcommon/codegen/src/main/resources/tlp/test.java create mode 100644 jcommon/codegen/src/main/resources/tlp/transfer.java create mode 100644 jcommon/codegen/src/main/resources/tlp/vo.java diff --git a/jcommon/codegen/pom.xml b/jcommon/codegen/pom.xml index 1ce33b9f6..a21ae573b 100644 --- a/jcommon/codegen/pom.xml +++ b/jcommon/codegen/pom.xml @@ -27,6 +27,23 @@ beetl 2.7.14 + + com.mybatis-flex + mybatis-flex-codegen + 1.7.8 + + + org.springframework + spring-jdbc + 5.3.29 + true + + + com.zaxxer + HikariCP + 4.0.3 + true + org.apache.commons commons-lang3 diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/FeatureGenerator.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/FeatureGenerator.java new file mode 100644 index 000000000..38812927d --- /dev/null +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/FeatureGenerator.java @@ -0,0 +1,149 @@ +package run.mone.ai.codegen; + +import com.mybatisflex.codegen.Generator; +import com.mybatisflex.codegen.config.GlobalConfig; +import com.zaxxer.hikari.HikariDataSource; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.jdbc.core.JdbcTemplate; +import run.mone.ai.codegen.bo.FeatureGeneratType; +import run.mone.ai.codegen.bo.FeatureGenerateBo; +import run.mone.ai.codegen.util.TemplateUtils; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * @author goodjava@qq.com, HawickMason@xiaomi.com + * @date 7/12/24 9:44 AM + */ +@Slf4j +public class FeatureGenerator { + + public static void generateWithTemplate(FeatureGenerateBo featureGenerateBo) { + + // 类型检查 + if (Objects.isNull(featureGenerateBo.getType())) { + log.warn("Empty generation type, will do noting!"); + return; + } + FeatureGeneratType featureGenType = featureGenerateBo.getType(); + if (FeatureGeneratType.CODE_WITH_TEMPLATE != featureGenType + && FeatureGeneratType.TABLE != featureGenType) { + log.warn("generate type:{} is not match with current call", featureGenType); + return; + } + + //配置数据源 + HikariDataSource dataSource = new HikariDataSource(); + dataSource.setJdbcUrl(featureGenerateBo.getJdbcUrl()); + dataSource.setUsername(featureGenerateBo.getUserName()); + dataSource.setPassword(featureGenerateBo.getPassword()); + + //创建mapper相关代码 + if (FeatureGeneratType.CODE_WITH_TEMPLATE == featureGenType) { + GlobalConfig globalConfig = createGlobalConfigUseStyle(featureGenerateBo); + Generator generator = new Generator(dataSource, globalConfig); + generator.generate(); + return; + } + + //创建table + if (FeatureGeneratType.TABLE == featureGenType) { + JdbcTemplate jt = new JdbcTemplate(dataSource); + jt.update(featureGenerateBo.getSql()); + } + } + + public static GlobalConfig createGlobalConfigUseStyle(FeatureGenerateBo featureGenerateBo) { + GlobalConfig globalConfig = new GlobalConfig(); + //设置根包 + String basePackage = featureGenerateBo.getBasePackage(); + globalConfig.setBasePackage(basePackage); + //表的名字 + globalConfig.setGenerateTable(featureGenerateBo.getTableName()); + globalConfig.setTablePrefix(""); + //设置生成 entity 并启用 Lombok + globalConfig.setEntityGenerateEnable(true); + globalConfig.setEntityWithLombok(true); + globalConfig.setServiceGenerateEnable(true); + globalConfig.setServiceImplGenerateEnable(true); + globalConfig.enableController(); + + //生成entity mapper service controller + String dir = featureGenerateBo.getBasePath(); + globalConfig.setMapperGenerateEnable(true); + globalConfig.getEntityConfig().setSourceDir(dir); + globalConfig.getMapperConfig().setSourceDir(dir); + globalConfig.getServiceConfig().setSourceDir(dir); + globalConfig.getServiceImplConfig().setSourceDir(dir); + globalConfig.getControllerConfig().setSourceDir(dir); + + globalConfig.setEntityPackage(basePackage + ".dao.entity"); + globalConfig.setMapperPackage(basePackage + ".dao.mapper"); + globalConfig.setServicePackage(basePackage + ".service"); + globalConfig.setServiceImplPackage(basePackage + ".service"); + globalConfig.setControllerPackage(basePackage + ".controller"); + + return globalConfig; + } + + public static void generateByTemplate(FeatureGenerateBo featureGenerateBo) { + String className = featureGenerateBo.getClassName(); + if (StringUtils.isEmpty(className)) { + return; + } + Map data = new HashMap<>(); + data.put("className", className); + data.put("author", "goodjava@qq.com"); + + String basePath = featureGenerateBo.getBasePath(); + String basePackage = featureGenerateBo.getBasePackage(); + String midPath = replaceDotWithSlash(basePackage); + log.info("generate by template with base path:{}", basePath); + // 调用方法并获取结果 + if (featureGenerateBo.isCreatePojo()) { + String pojo = TemplateUtils.renderTemplateFromFile("tlp/pojo.java", data); + TemplateUtils.writeStringToFile(pojo, getFilePath(basePath, featureGenerateBo.getServiceModulePath(), midPath, "/model/po/", className, ".java")); + } + + if (featureGenerateBo.isCreateVo()) { + String vo = TemplateUtils.renderTemplateFromFile("tlp/vo.java", data); + TemplateUtils.writeStringToFile(vo, getFilePath(basePath, featureGenerateBo.getApiModulePath(), midPath, "/api/vo/", className, "VO.java")); + } + + if (featureGenerateBo.isCreateTransfer()) { + String transfer = TemplateUtils.renderTemplateFromFile("tlp/transfer.java", data); + TemplateUtils.writeStringToFile(transfer, getFilePath(basePath, featureGenerateBo.getServiceModulePath(), midPath, "/model/transfer/", className, "Transfer.java")); + } + + if (featureGenerateBo.isCreateService()) { + String service = TemplateUtils.renderTemplateFromFile("tlp/service.java", data); + TemplateUtils.writeStringToFile(service, getFilePath(basePath, featureGenerateBo.getServiceModulePath(), midPath, "/service/", className, "Service.java")); + } + + if (featureGenerateBo.isCreateTest()) { + String cn = className + "ServiceTest.java"; + String test = TemplateUtils.renderTemplateFromFile("tlp/test.java", data); + TemplateUtils.writeStringToFile(test, basePath + "/" + featureGenerateBo.getServerModulePath() + "/src/test/java/run/mone/test/service/" + cn); + } + + if (featureGenerateBo.isCreateController()) { + String controller = TemplateUtils.renderTemplateFromFile("tlp/controller.java", data); + TemplateUtils.writeStringToFile(controller, getFilePath(basePath, featureGenerateBo.getServerModulePath(), midPath, "/controller/", className, "Controller.java")); + } + } + + private static String getFilePath(String basePath, String modulePath, String midPath, String subPath, String className, String suffix) { + return basePath + "/" + modulePath + "/src/main/java/" + midPath + subPath + className + suffix; + } + + // 将字符串中的"."替换为"/" + public static String replaceDotWithSlash(String input) { + if (input == null) { + return null; + } + return input.replace(".", "/"); + } +} diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/UnitTestGenerator.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/UnitTestGenerator.java new file mode 100644 index 000000000..3c9cc8556 --- /dev/null +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/UnitTestGenerator.java @@ -0,0 +1,12 @@ +package run.mone.ai.codegen; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author goodjava@qq.com, HawickMason@xiaomi.com + * @date 7/11/24 14:14 + */ +@Slf4j +public class UnitTestGenerator { + +} diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGeneratType.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGeneratType.java new file mode 100644 index 000000000..2773cc4e0 --- /dev/null +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGeneratType.java @@ -0,0 +1,39 @@ +package run.mone.ai.codegen.bo; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com, HawickMason@xiaomi.com + * @date 7/12/24 14:15 + */ +public enum FeatureGeneratType { + + CODE_WITH_GENERATOR(1, "使用mybatis-flex-generator生成"), + + CODE_WITH_TEMPLATE(2, "使用预制模板生成"), + + TABLE(3, "创建表"); + + private final int code; + + private final String desc; + + private static final Map valMap = Arrays.stream(values()).collect(Collectors.toMap(FeatureGeneratType::getCode, Function.identity())); + + FeatureGeneratType(int code, String desc) { + this.code = code; + this.desc = desc; + } + + public int getCode() { + return code; + } + + public String getDesc() { + return desc; + } + +} diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGenerateBo.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGenerateBo.java new file mode 100644 index 000000000..cce56c8e3 --- /dev/null +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGenerateBo.java @@ -0,0 +1,76 @@ +package run.mone.ai.codegen.bo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author goodjava@qq.com, HawickMason@xiaomi.com + * @date 7/12/24 14:10 + */ +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class FeatureGenerateBo { + + @Builder.Default + private FeatureGeneratType type = FeatureGeneratType.CODE_WITH_GENERATOR; + + @Builder.Default + private String tableName = ""; + + @Builder.Default + private String sql = ""; + + @Builder.Default + private String jdbcUrl = ""; + + @Builder.Default + private String userName = ""; + + @Builder.Default + private String password = ""; + + + @Builder.Default + private String basePackage = ""; + + @Builder.Default + private String className = "Dummy"; + + @Builder.Default + private String auth = ""; + + @Builder.Default + private String basePath = ""; + + @Builder.Default + private String serverModulePath = ""; + + @Builder.Default + private String serviceModulePath = ""; + + @Builder.Default + private String apiModulePath = ""; + + @Builder.Default + private boolean createPojo = false; + + @Builder.Default + private boolean createVo = false; + + @Builder.Default + private boolean createTransfer = false; + + @Builder.Default + private boolean createService = false; + + @Builder.Default + private boolean createTest = true; + + @Builder.Default + private boolean createController = false; + +} diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/util/TemplateUtils.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/util/TemplateUtils.java new file mode 100644 index 000000000..4d2805cbe --- /dev/null +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/util/TemplateUtils.java @@ -0,0 +1,73 @@ +package run.mone.ai.codegen.util; + +import com.google.common.collect.Lists; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import org.beetl.core.Configuration; +import org.beetl.core.Function; +import org.beetl.core.GroupTemplate; +import org.beetl.core.Template; +import org.beetl.core.resource.StringTemplateResourceLoader; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; + +/** + * @author goodjava@qq.com, HawickMason@xiaomi.com + * @date 7/12/24 11:05 AM + */ +@Slf4j +public class TemplateUtils { + + public static String renderTemplate(String template, Map m) { + return renderTemplate(template, m, Lists.newArrayList()); + } + + public static String renderTemplate(String template, Map m, List> functionList) { + try { + if (template == null || template.isEmpty()) { + return ""; + } + StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader(); + Configuration cfg = Configuration.defaultConfiguration(); + GroupTemplate gt = new GroupTemplate(resourceLoader, cfg); + functionList.forEach(it -> gt.registerFunction(it.getKey(), it.getValue())); + Template t = gt.getTemplate(template); + m.forEach((k, v) -> t.binding(k, v)); + String str = t.render(); + return str; + } catch (Throwable ex) { + log.error("renderTemplate", ex); + } + return ""; + } + + //读取resources下的模板文件,然后渲染成String(class) + @SneakyThrows + public static String renderTemplateFromFile(String templateFileName, Map m) { + try { + InputStream is = TemplateUtils.class.getClassLoader().getResourceAsStream(templateFileName); + //读取is成String + String template = new String(is.readAllBytes(), StandardCharsets.UTF_8); + return renderTemplate(template, m); + } catch (IOException ex) { + log.error("Error reading template file", ex); + } + return ""; + } + + //把String写到指定文件中(class) + public static void writeStringToFile(String content, String filePath) { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { + writer.write(content); + } catch (IOException ex) { + log.error("Error writing to file", ex); + } + } +} diff --git a/jcommon/codegen/src/main/resources/tlp/code_test.txt b/jcommon/codegen/src/main/resources/tlp/code_test.txt new file mode 100644 index 000000000..bc3775302 --- /dev/null +++ b/jcommon/codegen/src/main/resources/tlp/code_test.txt @@ -0,0 +1,2 @@ +name:${name} +name:${strutil.toLowerCase(name)} diff --git a/jcommon/codegen/src/main/resources/tlp/controller.java b/jcommon/codegen/src/main/resources/tlp/controller.java new file mode 100644 index 000000000..93807abe2 --- /dev/null +++ b/jcommon/codegen/src/main/resources/tlp/controller.java @@ -0,0 +1,41 @@ +package run.mone.controller; + +import com.xiaomi.mone.http.docs.annotations.HttpApiDoc; +import com.xiaomi.mone.http.docs.annotations.HttpApiModule; +import com.xiaomi.mone.http.docs.annotations.MiApiRequestMethod; +import com.xiaomi.youpin.docean.anno.Controller; +import com.xiaomi.youpin.docean.anno.RequestMapping; +import com.xiaomi.youpin.infra.rpc.Result; +import lombok.extern.slf4j.Slf4j; +import run.mone.api.vo.${className}VO; +import run.mone.model.po.${className}; +import run.mone.model.transfer.${className}Transfer; +import run.mone.service.${className}Service; + +import javax.annotation.Resource; + +/** + * @author ${author} + */ +@HttpApiModule(value = "${className}Controller", apiController = ${className}Controller.class) +@Controller +@RequestMapping(path = "/api/${strutil.toLowerCase(className)}") +@Slf4j +public class ${className}Controller extends MongodbController<${className}> { + + @Resource + private ${className}Service ${strutil.toLowerCase(className)}Service; + + public ${className}Controller() { + super(${className}.class); + } + + + @RequestMapping(path = "/create", method = "post") + @HttpApiDoc(value = "/api/${strutil.toLowerCase(className)}/create", method = MiApiRequestMethod.POST, apiName = "创建") + public Result create${className}(${className}VO ${strutil.toLowerCase(className)}VO) { + ${className} ${strutil.toLowerCase(className)} = ${className}Transfer.vo2po(${strutil.toLowerCase(className)}VO); + boolean result = ${strutil.toLowerCase(className)}Service.save(${strutil.toLowerCase(className)}); + return Result.success(result); + } +} \ No newline at end of file diff --git a/jcommon/codegen/src/main/resources/tlp/pojo.java b/jcommon/codegen/src/main/resources/tlp/pojo.java new file mode 100644 index 000000000..188a8846f --- /dev/null +++ b/jcommon/codegen/src/main/resources/tlp/pojo.java @@ -0,0 +1,32 @@ +package run.mone.model.po; + +import dev.morphia.annotations.Entity; +import dev.morphia.annotations.Id; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import run.mone.bo.MongoBo; + +/** + * @author ${author} + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Entity +public class ${className} implements MongoBo { + + @Id + private String id; + + private long ctime; + + private long utime; + + private int state; + + private int version; + +} \ No newline at end of file diff --git a/jcommon/codegen/src/main/resources/tlp/service.java b/jcommon/codegen/src/main/resources/tlp/service.java new file mode 100644 index 000000000..910f52f3f --- /dev/null +++ b/jcommon/codegen/src/main/resources/tlp/service.java @@ -0,0 +1,20 @@ +package run.mone.service; + +import com.xiaomi.youpin.docean.anno.Service; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import run.mone.model.po.${className}; + + +/** + * @author ${author} + */ +@Data +@Service +@Slf4j +public class ${className}Service extends MongoService<${className}> { + + public ${className}Service() { + super(${className}.class); + } +} \ No newline at end of file diff --git a/jcommon/codegen/src/main/resources/tlp/test.java b/jcommon/codegen/src/main/resources/tlp/test.java new file mode 100644 index 000000000..2c5eb309e --- /dev/null +++ b/jcommon/codegen/src/main/resources/tlp/test.java @@ -0,0 +1,32 @@ +package run.mone.test.service; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import run.mone.junit.DoceanConfiguration; +import run.mone.junit.DoceanExtension; +import javax.annotation.Resource; +import run.mone.service.${className}Service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import run.mone.bo.User; +import run.mone.common.Result; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author ${author} + */ +@ExtendWith(DoceanExtension.class) +@DoceanConfiguration(basePackage = {"run.mone", "com.xiaomi.youpin.docean.plugin", "com.xiaomi.mone.http.docs.core"}) +public class ${className}ServiceTest { + + + @Resource + private ${className}Service ${strutil.toLowerCase(className)}Service; + + +} \ No newline at end of file diff --git a/jcommon/codegen/src/main/resources/tlp/transfer.java b/jcommon/codegen/src/main/resources/tlp/transfer.java new file mode 100644 index 000000000..ce469927c --- /dev/null +++ b/jcommon/codegen/src/main/resources/tlp/transfer.java @@ -0,0 +1,24 @@ +package run.mone.model.transfer; + +import run.mone.api.vo.${className}VO; +import run.mone.model.po.${className}; +import com.xiaomi.youpin.docean.common.BeanUtils; + + +/** + * @author ${author} + */ +public class ${className}Transfer { + + public static ${className}VO po2vo(${className} po) { + ${className}VO vo = new ${className}VO(); + BeanUtils.copy(po, vo); + return vo; + } + + public static ${className} vo2po(${className}VO vo) { + ${className} po = new ${className}(); + BeanUtils.copy(vo, po); + return po; + } +} \ No newline at end of file diff --git a/jcommon/codegen/src/main/resources/tlp/vo.java b/jcommon/codegen/src/main/resources/tlp/vo.java new file mode 100644 index 000000000..1ed22d2ab --- /dev/null +++ b/jcommon/codegen/src/main/resources/tlp/vo.java @@ -0,0 +1,21 @@ +package run.mone.api.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author ${author} + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ${className}VO implements Serializable { + + private String id; + +} \ No newline at end of file From ed52ad71eb2903c57709324151c401b8e3956a3b Mon Sep 17 00:00:00 2001 From: wm Date: Wed, 17 Jul 2024 14:28:39 +0800 Subject: [PATCH 12/14] Add.gitignore, Dockerfile, mybatis-flex.config, and update pom.xml in private-knowledge project --- m78-all/private-knowledge/.gitignore | 26 + m78-all/private-knowledge/Dockerfile | 13 + m78-all/private-knowledge/mybatis-flex.config | 1 + m78-all/private-knowledge/pom.xml | 146 + .../private-knowledge-api/pom.xml | 38 + .../run/mone/knowledge/api/DemoProvider.java | 11 + .../knowledge/api/DubboHealthProvider.java | 9 + .../api/IKnowledgeVectorProvider.java | 27 + .../api/constant/CommonConstant.java | 11 + .../mone/knowledge/api/dto/DemoReqDto.java | 10 + .../mone/knowledge/api/dto/DemoResDto.java | 11 + .../knowledge/api/dto/KnowledgeTagInfo.java | 13 + .../api/dto/KnowledgeVectorDetailDto.java | 37 + .../api/dto/KnowledgeVectorDetailFullDto.java | 29 + .../knowledge/api/dto/KnowledgeVectorDto.java | 35 + .../dto/SimilarKnowledgeVectorFullQry.java | 21 + .../api/dto/SimilarKnowledgeVectorQry.java | 26 + .../api/dto/SimilarKnowledgeVectorRsp.java | 21 + .../mone/knowledge/api/dto/TagsFullInfo.java | 21 + .../run/mone/knowledge/api/dto/TagsInfo.java | 24 + .../mone/knowledge/api/dto/VectorData.java | 68 + .../mone/knowledge/api/dto/VectorLimits.java | 44 + .../api/dto/embedding/SimilarQry.java | 21 + .../api/dto/embedding/SimilarQryBase.java | 18 + .../api/enums/KnowledgeTypeEnum.java | 56 + .../private-knowledge-common/pom.xml | 26 + .../run/mone/knowledge/common/Constant.java | 9 + .../private-knowledge-server/pom.xml | 142 + .../server/PrivateKnowledgeBootstrap.java | 29 + .../server/config/DataSourceConfig.java | 49 + .../server/config/DubboConfiguration.java | 60 + .../config/MybatisFlexConfiguration.java | 25 + .../server/config/NacosConfiguration.java | 14 + .../controller/KnowledgeVectorController.java | 47 + .../server/controller/TestController.java | 46 + .../server/provider/DemoProviderImpl.java | 32 + .../provider/DubboHealthProviderImpl.java | 24 + .../provider/KnowledgeVectorProviderImpl.java | 370 + .../src/main/resources/application.properties | 23 + .../src/main/resources/config/dev.properties | 23 + .../main/resources/config/online.properties | 23 + .../main/resources/config/staging.properties | 23 + .../src/main/resources/dubbo.properties | 1 + .../src/main/resources/logback.xml | 59 + .../src/main/resources/sql/20240612.sql | 3 + .../src/main/resources/sql/init.sql | 30 + .../test/java/run/mone/test/DbCodegen.java | 76 + .../run/mone/test/VectorProviderTest.java | 84 + .../private-knowledge-service/pom.xml | 79 + .../mone/knowledge/service/DemoService.java | 29 + .../knowledge/service/EmbeddingService.java | 55 + .../knowledge/service/OzVectorDbService.java | 42 + .../knowledge/service/RedisVectorService.java | 68 + .../knowledge/service/common/CommonUtils.java | 25 + .../mone/knowledge/service/dao/DemoDao.java | 13 + .../service/dao/entity/DemoEntity.java | 27 + .../knowledge/service/dao/entity/M78Test.java | 60 + .../dao/entity/VKnowledgeVectorDetailPo.java | 66 + .../dao/entity/VKnowledgeVectorMetaPo.java | 87 + .../service/dao/mapper/M78TestMapper.java | 14 + .../mapper/VKnowledgeVectorDetailMapper.java | 14 + .../mapper/VKnowledgeVectorMetaMapper.java | 28 + .../knowledge/service/exceptions/ExCodes.java | 31 + .../service/impl/OzVectorDbServiceImpl.java | 63 + .../service/impl/RedisVectorServiceImpl.java | 229 + .../impl/VectorDtoTruncateService.java | 102 + .../knowledge/service/rpc/DemoDepRpc.java | 20 + .../service/rpc/dto/DemoDepReqDto.java | 19 + .../service/rpc/dto/DemoDepResDto.java | 17 + m78-all/z-desensitization/.gitignore | 24 + m78-all/z-desensitization/README.md | 5 + m78-all/z-desensitization/pom.xml | 166 + .../z-desensitization-api/pom.xml | 28 + .../api/bo/DesensitizeReq.java | 68 + .../api/bo/SensitiveWordConfigBo.java | 51 + .../api/common/CodeTypeEnum.java | 20 + .../api/common/SensitiveWordTypeEnum.java | 35 + .../api/service/CodeDesensitizeService.java | 25 + .../api/service/DubboHealthService.java | 10 + .../z-desensitization-app/pom.xml | 56 + .../java/run/mone/antlr/golang/Field.java | 22 + .../java/run/mone/antlr/golang/GoCode.java | 107 + .../java/run/mone/antlr/golang/GoLexer.interp | 301 + .../java/run/mone/antlr/golang/GoLexer.java | 603 ++ .../java/run/mone/antlr/golang/GoLexer.tokens | 153 + .../java/run/mone/antlr/golang/GoMethod.java | 22 + .../java/run/mone/antlr/golang/GoParam.java | 18 + .../run/mone/antlr/golang/GoParser.interp | 295 + .../java/run/mone/antlr/golang/GoParser.java | 7752 +++++++++++++++++ .../run/mone/antlr/golang/GoParser.tokens | 153 + .../run/mone/antlr/golang/GoParserBase.java | 28 + .../antlr/golang/GoParserBaseListener.java | 1286 +++ .../mone/antlr/golang/GoParserListener.java | 1049 +++ .../run/mone/antlr/golang/ParseResult.java | 22 + .../controller/TestController.java | 29 + .../z/desensitization/dto/DesensitizeRsp.java | 22 + .../mapper/ZDesensitizationRecordMapper.java | 40 + .../pojo/ZDesensitizationRecord.java | 154 + .../pojo/ZDesensitizationRecordExample.java | 511 ++ .../service/AiCodeDesensitizeService.java | 49 + .../service/CodeDesensitizeServiceImpl.java | 169 + .../service/DubboHealthServiceImpl.java | 16 + .../service/RecordService.java | 37 + .../service/common/ClassUtils.java | 57 + .../service/common/CodeDesensitizeUtils.java | 214 + .../service/common/CodeExtractorUtils.java | 69 + .../service/common/CodeParseUtils.java | 69 + .../service/common/Consts.java | 20 + .../service/common/HttpClientUtil.java | 138 + .../common/NewCodeDesensitizeUtils.java | 335 + .../service/common/ZNormalizer.java | 25 + .../desensitization/app/test/GoCodeTest.java | 87 + .../app/test/JavaCodeTest.java | 96 + .../z/desensitization/app/test/MyTest.java | 108 + .../z/desensitization/app/test/NewTest.java | 81 + .../mone/z/desensitization/app/test/test.go | 33 + .../mone/z/desensitization/app/test/test2.go | 3 + .../z-desensitization-debug/pom.xml | 23 + .../z-desensitization-domain/pom.xml | 67 + .../domain/gateway/DemoGateway.java | 10 + .../domain/model/DemoReqEntiry.java | 10 + .../domain/model/DemoResEntiry.java | 16 + .../z-desensitization-infrastructure/pom.xml | 26 + .../gateway/DemoGatewayImpl.java | 22 + .../z-desensitization-server/pom.xml | 193 + .../bootstrap/ZDesensitizationBootstrap.java | 35 + .../src/main/resources/application.properties | 17 + .../src/main/resources/config/c3.properties | 10 + .../src/main/resources/config/c4.properties | 10 + .../src/main/resources/config/dev.properties | 10 + .../main/resources/config/preview.properties | 10 + .../main/resources/config/staging.properties | 10 + .../src/main/resources/dubbo.properties | 1 + .../src/main/resources/generatorConfig.xml | 70 + .../src/main/resources/logback.xml | 59 + .../mapper/ZDesensitizationRecordMapper.xml | 327 + .../src/main/resources/sql/init.sql | 9 + 137 files changed, 18639 insertions(+) create mode 100644 m78-all/private-knowledge/.gitignore create mode 100644 m78-all/private-knowledge/Dockerfile create mode 100644 m78-all/private-knowledge/mybatis-flex.config create mode 100644 m78-all/private-knowledge/pom.xml create mode 100644 m78-all/private-knowledge/private-knowledge-api/pom.xml create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/DemoProvider.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/DubboHealthProvider.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/IKnowledgeVectorProvider.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/constant/CommonConstant.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/DemoReqDto.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/DemoResDto.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeTagInfo.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDetailDto.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDetailFullDto.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDto.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorFullQry.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorQry.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorRsp.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/TagsFullInfo.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/TagsInfo.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/VectorData.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/VectorLimits.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/embedding/SimilarQry.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/embedding/SimilarQryBase.java create mode 100644 m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/enums/KnowledgeTypeEnum.java create mode 100644 m78-all/private-knowledge/private-knowledge-common/pom.xml create mode 100644 m78-all/private-knowledge/private-knowledge-common/src/main/java/run/mone/knowledge/common/Constant.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/pom.xml create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/PrivateKnowledgeBootstrap.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/DataSourceConfig.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/DubboConfiguration.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/MybatisFlexConfiguration.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/NacosConfiguration.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/controller/KnowledgeVectorController.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/controller/TestController.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/DemoProviderImpl.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/DubboHealthProviderImpl.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/KnowledgeVectorProviderImpl.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/resources/application.properties create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/dev.properties create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/online.properties create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/staging.properties create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/resources/dubbo.properties create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/resources/logback.xml create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/resources/sql/20240612.sql create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/main/resources/sql/init.sql create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/test/java/run/mone/test/DbCodegen.java create mode 100644 m78-all/private-knowledge/private-knowledge-server/src/test/java/run/mone/test/VectorProviderTest.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/pom.xml create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/DemoService.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/EmbeddingService.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/OzVectorDbService.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/RedisVectorService.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/common/CommonUtils.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/DemoDao.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/DemoEntity.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/M78Test.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/VKnowledgeVectorDetailPo.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/VKnowledgeVectorMetaPo.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/M78TestMapper.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/VKnowledgeVectorDetailMapper.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/VKnowledgeVectorMetaMapper.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/exceptions/ExCodes.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/OzVectorDbServiceImpl.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/RedisVectorServiceImpl.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/VectorDtoTruncateService.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/DemoDepRpc.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/dto/DemoDepReqDto.java create mode 100644 m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/dto/DemoDepResDto.java create mode 100644 m78-all/z-desensitization/.gitignore create mode 100644 m78-all/z-desensitization/README.md create mode 100644 m78-all/z-desensitization/pom.xml create mode 100644 m78-all/z-desensitization/z-desensitization-api/pom.xml create mode 100644 m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/bo/DesensitizeReq.java create mode 100644 m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/bo/SensitiveWordConfigBo.java create mode 100644 m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/common/CodeTypeEnum.java create mode 100644 m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/common/SensitiveWordTypeEnum.java create mode 100644 m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/service/CodeDesensitizeService.java create mode 100644 m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/service/DubboHealthService.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/pom.xml create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/Field.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoCode.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.interp create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.tokens create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoMethod.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParam.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.interp create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.tokens create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserBase.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserBaseListener.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserListener.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/ParseResult.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/controller/TestController.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/dto/DesensitizeRsp.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/mapper/ZDesensitizationRecordMapper.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/pojo/ZDesensitizationRecord.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/pojo/ZDesensitizationRecordExample.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/AiCodeDesensitizeService.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/CodeDesensitizeServiceImpl.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/DubboHealthServiceImpl.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/RecordService.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/ClassUtils.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeDesensitizeUtils.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeExtractorUtils.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeParseUtils.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/Consts.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/HttpClientUtil.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/NewCodeDesensitizeUtils.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/ZNormalizer.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/GoCodeTest.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/JavaCodeTest.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/MyTest.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/NewTest.java create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/test.go create mode 100644 m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/test2.go create mode 100644 m78-all/z-desensitization/z-desensitization-debug/pom.xml create mode 100644 m78-all/z-desensitization/z-desensitization-domain/pom.xml create mode 100644 m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/gateway/DemoGateway.java create mode 100644 m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/model/DemoReqEntiry.java create mode 100644 m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/model/DemoResEntiry.java create mode 100644 m78-all/z-desensitization/z-desensitization-infrastructure/pom.xml create mode 100644 m78-all/z-desensitization/z-desensitization-infrastructure/src/main/java/run/mone/z/desensitization/gateway/DemoGatewayImpl.java create mode 100644 m78-all/z-desensitization/z-desensitization-server/pom.xml create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/java/run/mone/z/desensitization/bootstrap/ZDesensitizationBootstrap.java create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/resources/application.properties create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/c3.properties create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/c4.properties create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/dev.properties create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/preview.properties create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/staging.properties create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/resources/dubbo.properties create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/resources/generatorConfig.xml create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/resources/logback.xml create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/resources/mapper/ZDesensitizationRecordMapper.xml create mode 100644 m78-all/z-desensitization/z-desensitization-server/src/main/resources/sql/init.sql diff --git a/m78-all/private-knowledge/.gitignore b/m78-all/private-knowledge/.gitignore new file mode 100644 index 000000000..6dc90ad1b --- /dev/null +++ b/m78-all/private-knowledge/.gitignore @@ -0,0 +1,26 @@ +*.bak +build_info.properties +.classpath +dependency-reduced-pom.xml +*.diff +.DS_Store + +# IDEA +.idea/ +*.iml +logs/ +log/ + +# eclipse (Scala IDE) +.project +.settings/ +.tags* +target/ +test-output/ +nohup* +*.log +*.swp +*.pyc +.sbtserver* +/.java-version +/private-knowledge-server/src/main/resources/athena/athena_module.md diff --git a/m78-all/private-knowledge/Dockerfile b/m78-all/private-knowledge/Dockerfile new file mode 100644 index 000000000..a9070bd12 --- /dev/null +++ b/m78-all/private-knowledge/Dockerfile @@ -0,0 +1,13 @@ +FROM openjdk:8 + +ENV APP_HOME /opt/app + +RUN mkdir -p ${APP_HOME} + +RUN echo 'Asia/Shanghai' >/etc/timezone + +COPY private-knowledge-server/target/private-knowledge-server-*.jar ${APP_HOME}/private-knowledge-server.jar + +WORKDIR ${APP_HOME} + +ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar private-knowledge-server.jar"] \ No newline at end of file diff --git a/m78-all/private-knowledge/mybatis-flex.config b/m78-all/private-knowledge/mybatis-flex.config new file mode 100644 index 000000000..a6524481c --- /dev/null +++ b/m78-all/private-knowledge/mybatis-flex.config @@ -0,0 +1 @@ +processor.enable=true \ No newline at end of file diff --git a/m78-all/private-knowledge/pom.xml b/m78-all/private-knowledge/pom.xml new file mode 100644 index 000000000..f882c10e7 --- /dev/null +++ b/m78-all/private-knowledge/pom.xml @@ -0,0 +1,146 @@ + + + + 4.0.0 + run.mone.privateknowledge + private-knowledge + 1.0-SNAPSHOT-SNAPSHOT + pom + + + private-knowledge-api + private-knowledge-common + private-knowledge-service + private-knowledge-server + + + + org.springframework.boot + spring-boot-starter-parent + 2.3.12.RELEASE + + + + + + run.mone + infra-result + 1.4-SNAPSHOT + + + com.xiaomi.youpin + aop + 1.4-SNAPSHOT + + + com.xiaomi.youpin + common + 1.7-SNAPSHOT + + + ch.qos.logback + logback-classic + 1.1.2 + + + ch.qos.logback + logback-core + 1.1.2 + + + org.apache.dubbo + dubbo + 2.7.12-mone-v20-SNAPSHOT + + + com.xiaomi.mone + dubbo-auth + 2.7.12-SNAPSHOT + + + com.xiaomi.mone + dubbo-trace + 2.7.12-SNAPSHOT + + + com.alibaba + dubbo-registry-nacos + 1.2.1-mone-SNAPSHOT + + + com.alibaba.spring + spring-context-support + 1.0.10 + + + com.alibaba.nacos + nacos-spring-context + 0.3.6-mone-SNAPSHOT + + + com.alibaba.nacos + nacos-client + 1.2.1-mone-v7-SNAPSHOT + + + com.alibaba.nacos + nacos-api + 1.2.1-mone-v3-SNAPSHOT + + + com.mybatis-flex + mybatis-flex-spring-boot-starter + 1.7.3 + + + com.mybatis-flex + mybatis-flex-codegen + 1.7.8 + + + org.apache.commons + commons-math3 + 3.6.1 + + + redis.clients + jedis + 2.9.0 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + true + true + UTF-8 + + + ${project.basedir}/src/main/java + + + + + + + + + + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + diff --git a/m78-all/private-knowledge/private-knowledge-api/pom.xml b/m78-all/private-knowledge/private-knowledge-api/pom.xml new file mode 100644 index 000000000..b272520b8 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/pom.xml @@ -0,0 +1,38 @@ + + + + + private-knowledge + run.mone.privateknowledge + 1.0-SNAPSHOT-SNAPSHOT + + 4.0.0 + + private-knowledge-api + + + + + + run.mone + infra-result + + + + com.xiaomi.youpin + common + + + + org.projectlombok + lombok + 1.18.20 + + + + + + + \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/DemoProvider.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/DemoProvider.java new file mode 100644 index 000000000..0fbf1b965 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/DemoProvider.java @@ -0,0 +1,11 @@ +package run.mone.knowledge.api; + +import com.xiaomi.data.push.common.Health; +import run.mone.knowledge.api.dto.DemoReqDto; +import run.mone.knowledge.api.dto.DemoResDto; +import com.xiaomi.youpin.infra.rpc.Result; + +public interface DemoProvider { + + Result query(DemoReqDto reqDto); +} \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/DubboHealthProvider.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/DubboHealthProvider.java new file mode 100644 index 000000000..11bc0f3c5 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/DubboHealthProvider.java @@ -0,0 +1,9 @@ +package run.mone.knowledge.api; + +import com.xiaomi.youpin.infra.rpc.Result; +import com.xiaomi.data.push.common.Health; + +public interface DubboHealthProvider { + + Result health(); +} \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/IKnowledgeVectorProvider.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/IKnowledgeVectorProvider.java new file mode 100644 index 000000000..8a06654b6 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/IKnowledgeVectorProvider.java @@ -0,0 +1,27 @@ +package run.mone.knowledge.api; + +import com.xiaomi.youpin.infra.rpc.Result; +import run.mone.knowledge.api.dto.KnowledgeVectorDto; +import run.mone.knowledge.api.dto.SimilarKnowledgeVectorQry; +import run.mone.knowledge.api.dto.SimilarKnowledgeVectorRsp; + +import java.util.List; + +/** + * @author wmin + * @date 2024/2/5 + */ +public interface IKnowledgeVectorProvider { + + Result insertOrUpdateKnowledgeVector(KnowledgeVectorDto param); + + Result deleteKnowledgeVector(KnowledgeVectorDto param); + + /** + * 查询相似的topN条向量数据 + * @param qry + * @return + */ + Result> qrySimilarKnowledgeVector(SimilarKnowledgeVectorQry qry); + +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/constant/CommonConstant.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/constant/CommonConstant.java new file mode 100644 index 000000000..a97b8a2e0 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/constant/CommonConstant.java @@ -0,0 +1,11 @@ +package run.mone.knowledge.api.constant; + +/** + * @author wmin + * @date 2024/2/5 + */ +public class CommonConstant { + + public static final String PRIVATE_KNOWLEDGE_BASE_REDIS_PREFIX = "private_knowledge_base_"; + +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/DemoReqDto.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/DemoReqDto.java new file mode 100644 index 000000000..25ed6394e --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/DemoReqDto.java @@ -0,0 +1,10 @@ +package run.mone.knowledge.api.dto; + +import lombok.Data; +import lombok.ToString; + +@ToString +@Data +public class DemoReqDto { + private Long id; +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/DemoResDto.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/DemoResDto.java new file mode 100644 index 000000000..de6ec8fa5 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/DemoResDto.java @@ -0,0 +1,11 @@ +package run.mone.knowledge.api.dto; + +import lombok.Data; +import lombok.ToString; + +@ToString +@Data +public class DemoResDto { + private String test1; + private String test2; +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeTagInfo.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeTagInfo.java new file mode 100644 index 000000000..5401fad2f --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeTagInfo.java @@ -0,0 +1,13 @@ +package run.mone.knowledge.api.dto; + +import lombok.Data; + +/** + * @author wmin + * @date 2024/2/5 + */ +@Data +public class KnowledgeTagInfo { + private Integer tagIndex; + private String tagValue; +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDetailDto.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDetailDto.java new file mode 100644 index 000000000..8c3ab3ad1 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDetailDto.java @@ -0,0 +1,37 @@ +package run.mone.knowledge.api.dto; + +import lombok.Data; +import run.mone.knowledge.api.enums.KnowledgeTypeEnum; + + +/** + * @author wmin + * @date 2024/2/5 + */ +@Data +public class KnowledgeVectorDetailDto { + + /** + * @see KnowledgeTypeEnum + */ + private String type; + + private String tag1; + + private String tag2; + + private String tag3; + + private String tag4; + + private String tag5; + + private String tag6; + + private String tag7; + + private String content; + + private double[] vector; + +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDetailFullDto.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDetailFullDto.java new file mode 100644 index 000000000..b599e4cc5 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDetailFullDto.java @@ -0,0 +1,29 @@ +package run.mone.knowledge.api.dto; + +import lombok.Data; + +import java.util.List; + +/** + * @author wmin + * @date 2024/2/19 + */ +@Data +public class KnowledgeVectorDetailFullDto { + + private KnowledgeVectorDetailDto detailDto; + + private String type; + + //完整的tags,七层 + private List fullTags; + + private String groupTag; + + private String leafTag; + + private int groupTagIndex; + + private int leafTagIndex; + +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDto.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDto.java new file mode 100644 index 000000000..133dd0974 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/KnowledgeVectorDto.java @@ -0,0 +1,35 @@ +package run.mone.knowledge.api.dto; + +import lombok.Data; +import run.mone.knowledge.api.enums.KnowledgeTypeEnum; + +import java.util.List; + + +/** + * @author wmin + * @date 2024/2/5 + */ +@Data +public class KnowledgeVectorDto { + + /** + * @see KnowledgeTypeEnum + */ + private String type; + + /** + * todo 是否需要向量化处理,true则DetailDto中content必传,false则vector必传 + */ + private boolean needEmbedding; + + private List knowledgeVectorDetailDtoList; + + /** + * 是否强制删除 + * 默认false,软删,对于软删的meta,不再insert or update其关联的detail + * 编程助手upload code场景,需要强制删除,因为后续同一个group id可能需要更新 + */ + private boolean forceDelete; + +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorFullQry.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorFullQry.java new file mode 100644 index 000000000..ef8590f1f --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorFullQry.java @@ -0,0 +1,21 @@ +package run.mone.knowledge.api.dto; + +import lombok.Data; + +import java.util.List; + +/** + * @author wmin + * @date 2024/2/19 + */ +@Data +public class SimilarKnowledgeVectorFullQry { + + private SimilarKnowledgeVectorQry vectorQry; + + private List tags; + + private String groupTag; + + private String leafTag; +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorQry.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorQry.java new file mode 100644 index 000000000..59c208db4 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorQry.java @@ -0,0 +1,26 @@ +package run.mone.knowledge.api.dto; + +import lombok.Data; + +import java.util.List; + +/** + * @author wmin + * @date 2024/2/5 + */ +@Data +public class SimilarKnowledgeVectorQry { + + private String type; + + private List tagsInfoList; + + private String questionContent; + + private double[] questionVector; + + private Integer topN; + + private Double similarity; + +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorRsp.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorRsp.java new file mode 100644 index 000000000..446750b1d --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/SimilarKnowledgeVectorRsp.java @@ -0,0 +1,21 @@ +package run.mone.knowledge.api.dto; + +import lombok.Builder; +import lombok.Data; + + +/** + * @author wmin + * @date 2024/2/5 + */ +@Data +@Builder +public class SimilarKnowledgeVectorRsp { + + private Double similarity; + + private String group; + + private String leaf; + +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/TagsFullInfo.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/TagsFullInfo.java new file mode 100644 index 000000000..3bdd1cc2e --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/TagsFullInfo.java @@ -0,0 +1,21 @@ +package run.mone.knowledge.api.dto; + +import lombok.Data; + +import java.util.List; + +/** + * @author wmin + * @date 2024/2/22 + */ +@Data +public class TagsFullInfo { + + private TagsInfo tagsInfo; + + private List tags; + + private String groupTag; + + private String leafTag; +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/TagsInfo.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/TagsInfo.java new file mode 100644 index 000000000..616e0fa5e --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/TagsInfo.java @@ -0,0 +1,24 @@ +package run.mone.knowledge.api.dto; + +import lombok.Data; + +/** + * @author wmin + * @date 2024/2/22 + */ +@Data +public class TagsInfo { + private String tag1; + + private String tag2; + + private String tag3; + + private String tag4; + + private String tag5; + + private String tag6; + + private String tag7; +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/VectorData.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/VectorData.java new file mode 100644 index 000000000..6253e4a50 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/VectorData.java @@ -0,0 +1,68 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 run.mone.knowledge.api.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.tuple.Pair; + +import java.io.Serializable; + +/** + * @author shanwb + * @date 2024-02-06 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class VectorData implements Serializable { + + public static String SPLIT_CHAR = "_#_"; + + private String type; + + /** + * 向量元数据倒数第二级节点,比如:文件id、模块id等 + */ + private String group; + + /** + * 向量元数据叶子节点,比如文本块id、类id等 + */ + private String leaf; + + private double[] vector; + + private Double similarity; + + public String getGroupKey() { + return makeGroupKey(type, group); + } + + public static String makeGroupKey(String type, String group) { + return type + SPLIT_CHAR + group; + } + + public static Pair parseGroupKey(String groupKey) { + String[] arr = groupKey.split(SPLIT_CHAR); + return Pair.of(arr[0], arr[1]); + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/VectorLimits.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/VectorLimits.java new file mode 100644 index 000000000..0589a48f1 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/VectorLimits.java @@ -0,0 +1,44 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 run.mone.knowledge.api.dto; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author shanwb + * @date 2024-02-06 + */ +@Data +@Builder +public class VectorLimits implements Serializable { + + private Integer topN = 3; + + private Double similarity; + + public Integer getRealTopN() { + if (null == similarity && null == topN) { + this.setTopN(3); + } + + return getTopN(); + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/embedding/SimilarQry.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/embedding/SimilarQry.java new file mode 100644 index 000000000..8a9965b8f --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/embedding/SimilarQry.java @@ -0,0 +1,21 @@ +package run.mone.knowledge.api.dto.embedding; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * @author wmin + * @date 2024/2/6 + */ +@Data +@Builder +public class SimilarQry { + + private String questionContent; + + private List baseList; + + private Integer limit = 1; +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/embedding/SimilarQryBase.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/embedding/SimilarQryBase.java new file mode 100644 index 000000000..ac9b31944 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/dto/embedding/SimilarQryBase.java @@ -0,0 +1,18 @@ +package run.mone.knowledge.api.dto.embedding; + +import lombok.Builder; +import lombok.Data; + +/** + * @author wmin + * @date 2024/2/6 + */ +@Data +@Builder +public class SimilarQryBase { + + private Long id; + + private byte[] embedding; + +} diff --git a/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/enums/KnowledgeTypeEnum.java b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/enums/KnowledgeTypeEnum.java new file mode 100644 index 000000000..8e5baf877 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-api/src/main/java/run/mone/knowledge/api/enums/KnowledgeTypeEnum.java @@ -0,0 +1,56 @@ +package run.mone.knowledge.api.enums; + +/** + * @author goodjava@qq.com + * @date 2024/1/15 14:44 + */ +public enum KnowledgeTypeEnum { + + //项目代码 project-module-class + project_code("project_code", 1, 2), + //普通文档 knowledgeBase-file-block + normal_document("normal_document", 1, 2); + + private String typeName; + private int groupTagIndex; + private int leafTagIndex; + + KnowledgeTypeEnum(String typeName, int groupTagIndex, int leafTagIndex) { + this.typeName = typeName; + this.groupTagIndex = groupTagIndex; + this.leafTagIndex = leafTagIndex; + } + + public String getTypeName() { + return typeName; + } + + public int getGroupTagIndex() { + return groupTagIndex; + } + + public int getLeafTagIndex() { + return leafTagIndex; + } + + //判断某个string是否属于当前enum(class) + public static boolean isEnumValueValid(String value) { + for (KnowledgeTypeEnum enumValue : KnowledgeTypeEnum.values()) { + if (enumValue.typeName.equals(value)) { + return true; + } + } + return false; + } + + //根据传入的typeName获取该enum(class) + public static KnowledgeTypeEnum getEnumByTypeName(String typeName) { + for (KnowledgeTypeEnum enumValue : KnowledgeTypeEnum.values()) { + if (enumValue.typeName.equals(typeName)) { + return enumValue; + } + } + return null; + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-common/pom.xml b/m78-all/private-knowledge/private-knowledge-common/pom.xml new file mode 100644 index 000000000..adee59787 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-common/pom.xml @@ -0,0 +1,26 @@ + + + + + private-knowledge + run.mone.privateknowledge + 1.0-SNAPSHOT-SNAPSHOT + + 4.0.0 + + private-knowledge-common + + + + ch.qos.logback + logback-classic + + + ch.qos.logback + logback-core + + + + \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-common/src/main/java/run/mone/knowledge/common/Constant.java b/m78-all/private-knowledge/private-knowledge-common/src/main/java/run/mone/knowledge/common/Constant.java new file mode 100644 index 000000000..cc42b74ea --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-common/src/main/java/run/mone/knowledge/common/Constant.java @@ -0,0 +1,9 @@ +package run.mone.knowledge.common; + + +/** + * @author bot + */ +public class Constant { + public final static int DEF_DUBBO_TIMEOUT = 30000; +} \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-server/pom.xml b/m78-all/private-knowledge/private-knowledge-server/pom.xml new file mode 100644 index 000000000..9877a0956 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/pom.xml @@ -0,0 +1,142 @@ + + + + private-knowledge + run.mone.privateknowledge + 1.0-SNAPSHOT-SNAPSHOT + + 4.0.0 + + private-knowledge-server + + + + + private-knowledge-service + run.mone.privateknowledge + 1.0-SNAPSHOT-SNAPSHOT + + + com.xiaomi.mone + dubbo-trace + + + org.springframework.boot + spring-boot-starter-test + + + com.xiaomi.youpin + aop + + + com.alibaba + dubbo-registry-nacos + + + com.alibaba.spring + spring-context-support + + + com.alibaba.nacos + nacos-spring-context + + + com.alibaba.nacos + nacos-client + + + + + + + + + src/main/resources + true + + + src/main/resources/META-INF + true + + app.properties + + META-INF/ + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.7.5 + + run.mone.knowledge.server.PrivateKnowledgeBootstrap + + + + + repackage + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + + + + + + + dev + + dev + + + true + + + + src/main/resources/config/dev.properties + + + + + + staging + + staging + + + + src/main/resources/config/staging.properties + + + + + + online + + online + + + + src/main/resources/config/online.properties + + + + + + + + \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/PrivateKnowledgeBootstrap.java b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/PrivateKnowledgeBootstrap.java new file mode 100644 index 000000000..3fc00e9a1 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/PrivateKnowledgeBootstrap.java @@ -0,0 +1,29 @@ +package run.mone.knowledge.server; + +import org.apache.dubbo.config.spring.context.annotation.DubboComponentScan; +import org.mybatis.spring.annotation.MapperScan; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; + +/** + * @author bot + */ +@EnableAutoConfiguration +@ComponentScan(basePackages = {"run.mone", "com.xiaomi.youpin", "com.xiaomi.data.push.redis"}) +@DubboComponentScan(basePackages = "run.mone") +@MapperScan("run.mone.knowledge.service.dao") +public class PrivateKnowledgeBootstrap { + private static final Logger logger = LoggerFactory.getLogger(PrivateKnowledgeBootstrap.class); + + public static void main(String... args) { + try { + SpringApplication.run(PrivateKnowledgeBootstrap.class, args); + } catch (Throwable throwable) { + logger.error(throwable.getMessage(), throwable); + System.exit(-1); + } + } +} \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/DataSourceConfig.java b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/DataSourceConfig.java new file mode 100644 index 000000000..e7dc8cd57 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/DataSourceConfig.java @@ -0,0 +1,49 @@ +package run.mone.knowledge.server.config; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.sql.DataSource; + +@Configuration +public class DataSourceConfig { + + @Value("${db_pwd}") + private String db_pwd; + + @Value("${db_url}") + private String db_url; + + @Value("${db_user_name}") + private String db_user_name; + + @Value("${db_maximumPoolSize:10}") + private int maximumPoolSize; + + @Value("${db_minimumIdle:5}") + private int minimumIdle; + + @Bean + public DataSource getDataSource() { + HikariConfig config = new HikariConfig(); + config.setJdbcUrl(db_url); + config.setUsername(db_user_name); + config.setPassword(db_pwd); + config.setMaximumPoolSize(maximumPoolSize); + config.setMinimumIdle(minimumIdle); + + // 连接超时时间(毫秒) + config.setConnectionTimeout(30 * 1000); + // 连接空闲超时时间(毫秒) + config.setIdleTimeout(600 * 1000); + // 每次执行SQL前是否自动检查连接有效性 + config.setConnectionTestQuery("SELECT 1"); + // 连接池名称,方便监控和日志记录 + config.setPoolName("M78KnowledgeDataSource"); + + return new HikariDataSource(config); + } +} diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/DubboConfiguration.java b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/DubboConfiguration.java new file mode 100644 index 000000000..d62af8c55 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/DubboConfiguration.java @@ -0,0 +1,60 @@ +package run.mone.knowledge.server.config; + +import com.google.common.collect.Maps; +import com.xiaomi.youpin.dubbo.common.DubboYoupinVersion; +import org.apache.commons.lang3.StringUtils; +import org.apache.dubbo.config.ApplicationConfig; +import org.apache.dubbo.config.ProtocolConfig; +import org.apache.dubbo.config.RegistryConfig; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class DubboConfiguration { + + @Value("${app.name}") + private String appName; + @Value("${dubbo.protocol.port}") + private int port; + + @Value("${server.port}") + private String httpGateWayPort; + + @Value("${dubbo.registry.address}") + private String regAddress; + + @Bean + public ApplicationConfig applicationConfig() { + ApplicationConfig applicationConfig = new ApplicationConfig(); + applicationConfig.setName(appName); + applicationConfig.setParameters(Maps.newHashMap()); + applicationConfig.getParameters().put("http_gateway_port", httpGateWayPort); + applicationConfig.getParameters().put("dubbo_version", new DubboYoupinVersion().toString()); + String prometheusPort = System.getenv("PROMETHEUS_PORT"); + if (StringUtils.isEmpty(prometheusPort)) { + prometheusPort = "4444"; + } + applicationConfig.getParameters().put("prometheus_port", prometheusPort); + applicationConfig.setQosEnable(false); + return applicationConfig; + } + + @Bean + public RegistryConfig registryConfig() { + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress(regAddress); + return registryConfig; + } + + @Bean + public ProtocolConfig protocolConfig() { + ProtocolConfig protocolConfig = new ProtocolConfig(); + protocolConfig.setPort(port); + protocolConfig.setTransporter("netty4"); + protocolConfig.setThreadpool("fixed"); + protocolConfig.setThreads(200); + return protocolConfig; + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/MybatisFlexConfiguration.java b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/MybatisFlexConfiguration.java new file mode 100644 index 000000000..287f00ffc --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/MybatisFlexConfiguration.java @@ -0,0 +1,25 @@ +package run.mone.knowledge.server.config; + +import com.mybatisflex.core.audit.AuditManager; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Configuration; + +/** + * @author HawickMason@xiaomi.com + * @date 1/10/24 3:40 PM + */ +@Configuration +@Slf4j +public class MybatisFlexConfiguration { + + public MybatisFlexConfiguration() { + //开启审计功能 + AuditManager.setAuditEnable(true); + + //设置 SQL 审计收集器 + AuditManager.setMessageCollector(auditMessage -> + log.info("sql audit :{}, cost: {}ms", auditMessage.getFullSql() + , auditMessage.getElapsedTime()) + ); + } +} diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/NacosConfiguration.java b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/NacosConfiguration.java new file mode 100644 index 000000000..5b95db9ff --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/config/NacosConfiguration.java @@ -0,0 +1,14 @@ +package run.mone.knowledge.server.config; + +import com.alibaba.nacos.api.annotation.NacosProperties; +import com.alibaba.nacos.api.config.annotation.NacosValue; +import com.alibaba.nacos.spring.context.annotation.config.EnableNacosConfig; +import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "${nacos.config.addrs}")) +@NacosPropertySource(dataId = "private-knowledge", autoRefreshed = true) +public class NacosConfiguration { + +} \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/controller/KnowledgeVectorController.java b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/controller/KnowledgeVectorController.java new file mode 100644 index 000000000..4af546305 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/controller/KnowledgeVectorController.java @@ -0,0 +1,47 @@ +package run.mone.knowledge.server.controller; + +import com.xiaomi.youpin.infra.rpc.Result; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import run.mone.knowledge.api.IKnowledgeVectorProvider; +import run.mone.knowledge.api.dto.KnowledgeVectorDto; +import run.mone.knowledge.api.dto.SimilarKnowledgeVectorQry; +import run.mone.knowledge.api.dto.SimilarKnowledgeVectorRsp; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +/** + * @author wmin + * @date 2024/2/20 + */ +@Slf4j +@RestController +@RequestMapping(value = "/api/knowledgeVector") +public class KnowledgeVectorController { + + @Resource + private IKnowledgeVectorProvider knowledgeVectorProvider; + + @PostMapping(value = "/addOrUpdate") + public Result insertOrUpdateKnowledgeVector(@RequestBody KnowledgeVectorDto knowledgeVectorDto, HttpServletRequest request) { + log.info("insertOrUpdateKnowledgeVector req:{}", knowledgeVectorDto.getKnowledgeVectorDetailDtoList().size()); + return knowledgeVectorProvider.insertOrUpdateKnowledgeVector(knowledgeVectorDto); + } + + @PostMapping(value = "/qrySimilar") + public Result> qrySimilarKnowledgeVector(@RequestBody SimilarKnowledgeVectorQry similarKnowledgeVectorQry, HttpServletRequest request) { + log.info("qrySimilarKnowledgeVector req:{}", similarKnowledgeVectorQry); + return knowledgeVectorProvider.qrySimilarKnowledgeVector(similarKnowledgeVectorQry); + } + + @PostMapping(value = "/delete") + public Result deleteKnowledgeVector(@RequestBody KnowledgeVectorDto knowledgeVectorDto, HttpServletRequest request) { + log.info("deleteKnowledgeVector req:{}", knowledgeVectorDto); + return knowledgeVectorProvider.deleteKnowledgeVector(knowledgeVectorDto); + } +} diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/controller/TestController.java b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/controller/TestController.java new file mode 100644 index 000000000..ed0509e55 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/controller/TestController.java @@ -0,0 +1,46 @@ +package run.mone.knowledge.server.controller; + +import com.xiaomi.data.push.redis.Redis; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequestMapping(value = "/api") +public class TestController { + + + @Autowired + private Redis redis; + + /** + * 进程心跳调用 + * + * @return + */ + @RequestMapping(value = "/isOk") + public String isOk() { + return "ok"; + } + + //从redis中读取指定key的值 + @RequestMapping(value = "/getValueFromRedis", method = RequestMethod.GET) + public ResponseEntity getValueFromRedis(@RequestParam("key") String key) { + String value = redis.get(key); + return value != null ? ResponseEntity.ok(value) : ResponseEntity.notFound().build(); + } + + //按指定key value写入redis + @RequestMapping(value = "/setValueToRedis", method = RequestMethod.POST) + public ResponseEntity setValueToRedis(@RequestParam("key") String key, @RequestParam("value") String value) { + redis.set(key, value); + return ResponseEntity.ok().build(); + } + + +} diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/DemoProviderImpl.java b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/DemoProviderImpl.java new file mode 100644 index 000000000..130f4c07f --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/DemoProviderImpl.java @@ -0,0 +1,32 @@ +package run.mone.knowledge.server.provider; + +import run.mone.knowledge.api.DemoProvider; +import run.mone.knowledge.api.dto.DemoReqDto; +import run.mone.knowledge.api.dto.DemoResDto; +import run.mone.knowledge.common.Constant; +import run.mone.knowledge.service.DemoService; +import com.xiaomi.youpin.infra.rpc.Result; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboService; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @author bot + */ +@Slf4j +@SuppressWarnings(value = "checkstyle:MagicNumber") +@DubboService(timeout = Constant.DEF_DUBBO_TIMEOUT, group = "${dubbo.group}") +public class DemoProviderImpl implements DemoProvider { + + @Autowired + private DemoService demoService; + + @Override + public Result query(DemoReqDto reqDto) { + //参数校验,用户信息校验等 + log.info("DemoProvider.query请求 reqDto={}", reqDto); + Result result = demoService.query(reqDto); + log.info("DemoProvider.query响应 result={}", result); + return result; + } +} diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/DubboHealthProviderImpl.java b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/DubboHealthProviderImpl.java new file mode 100644 index 000000000..3fb064df5 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/DubboHealthProviderImpl.java @@ -0,0 +1,24 @@ +package run.mone.knowledge.server.provider; + +import com.xiaomi.data.push.common.Health; +import run.mone.knowledge.api.DubboHealthProvider; +import run.mone.knowledge.common.Constant; +import com.xiaomi.youpin.infra.rpc.Result; +import com.xiaomi.youpin.qps.QpsAop; +import lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboService; +import org.springframework.beans.factory.annotation.Autowired; + +@DubboService(timeout = Constant.DEF_DUBBO_TIMEOUT, group = "${dubbo.group}", version="1.0") +@Slf4j +public class DubboHealthProviderImpl implements DubboHealthProvider { + + @Autowired + private QpsAop qpsAop; + + @Override + public Result health() { + long qps = qpsAop.getQps(); + return Result.success(new Health("0.0.1", "2019-11-11", qps)); + } +} diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/KnowledgeVectorProviderImpl.java b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/KnowledgeVectorProviderImpl.java new file mode 100644 index 000000000..f3bc8eaa0 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/java/run/mone/knowledge/server/provider/KnowledgeVectorProviderImpl.java @@ -0,0 +1,370 @@ +package run.mone.knowledge.server.provider; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.util.UpdateEntity; +import com.xiaomi.youpin.infra.rpc.Result; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.dubbo.config.annotation.DubboService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; +import run.mone.knowledge.api.IKnowledgeVectorProvider; +import run.mone.knowledge.api.enums.KnowledgeTypeEnum; +import run.mone.knowledge.api.dto.*; +import run.mone.knowledge.service.EmbeddingService; +import run.mone.knowledge.service.OzVectorDbService; +import run.mone.knowledge.service.RedisVectorService; +import run.mone.knowledge.service.dao.entity.VKnowledgeVectorDetailPo; +import run.mone.knowledge.service.dao.entity.VKnowledgeVectorMetaPo; +import run.mone.knowledge.service.dao.mapper.VKnowledgeVectorDetailMapper; +import run.mone.knowledge.service.dao.mapper.VKnowledgeVectorMetaMapper; +import run.mone.knowledge.service.exceptions.ExCodes; +import run.mone.knowledge.service.impl.VectorDtoTruncateService; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author wmin + * @date 2024/2/5 + */ +@Slf4j +@DubboService(interfaceClass = IKnowledgeVectorProvider.class, group = "${dubbo.group}", version = "1.0") +public class KnowledgeVectorProviderImpl implements IKnowledgeVectorProvider { + + public static Gson gson = new Gson(); + + @Resource + private VKnowledgeVectorDetailMapper detailMapper; + @Resource + private VKnowledgeVectorMetaMapper metaMapper; + @Autowired + private RedisVectorService redisVectorService; + @Autowired + private EmbeddingService embeddingService; + @Autowired + private OzVectorDbService ozVectorDbService; + + @Autowired + private VectorDtoTruncateService vectorDtoTruncateService; + + + @Transactional + @Override + public Result insertOrUpdateKnowledgeVector(KnowledgeVectorDto param) { + Pair checkRst = checkKnowledgeVectorDto(param, "insertOrUpdate"); + if (!checkRst.getKey()) { + return Result.fail(ExCodes.STATUS_BAD_REQUEST, checkRst.getValue()); + } + List vectorDataList = new ArrayList<>(); + + List knowledgeVectorDetailDtoList = param.getKnowledgeVectorDetailDtoList(); + KnowledgeTypeEnum typeEnum = KnowledgeTypeEnum.getEnumByTypeName(param.getType()); + + Pair tagsCheckRst = Pair.of(true, ""); + + for (KnowledgeVectorDetailDto detailDto : knowledgeVectorDetailDtoList){ + KnowledgeVectorDetailFullDto fullDto = vectorDtoTruncateService.getFullDto(detailDto, typeEnum); + log.info("insertOrUpdateKnowledgeVector fullDto: {}", fullDto.getFullTags()); + if (StringUtils.isBlank(fullDto.getGroupTag()) || StringUtils.isBlank(fullDto.getLeafTag())){ + log.error("tagsCheckRst failed, tags:{}", fullDto.getFullTags()); + tagsCheckRst = Pair.of(false, "groupTag/leafTag is empty. tags:"+fullDto.getFullTags()); + break; + } + + VKnowledgeVectorMetaPo vectorMeta = vectorDtoTruncateService.convertVectorMetaDtoToPo(fullDto); + Integer metaId = insertOrGetMeta(vectorMeta); + log.info("insertOrGetMeta id:{}", metaId); + if (metaId == -1){ + continue; + } + VKnowledgeVectorDetailPo vectorDetail = vectorDtoTruncateService.convertVectorDetailDtoToPo(fullDto); + vectorDetail.setMetaId(metaId); + //查询是否已有 + VKnowledgeVectorDetailPo dbVectorDetail = detailMapper.selectOneByQuery( + QueryWrapper.create().eq("type", vectorDetail.getType()).eq("meta_id", metaId).eq("leaf_tag", vectorDetail.getLeafTag()) + ); + Date currentTime = new Date(); + if (dbVectorDetail!=null){ + VKnowledgeVectorDetailPo updatePO = UpdateEntity.of(VKnowledgeVectorDetailPo.class, dbVectorDetail.getId()); + updatePO.setContent(vectorDetail.getContent()); + updatePO.setVector(vectorDetail.getVector()); + vectorDetail.setGmtModified(currentTime); + detailMapper.update(updatePO); + log.info("detail update :{}", dbVectorDetail.getId()); + } else { + vectorDetail.setGmtCreate(currentTime); + vectorDetail.setGmtModified(currentTime); + vectorDetail.setEmbeddingStatus(2); + detailMapper.insert(vectorDetail); + log.info("detail insert :{}", vectorDetail.getId()); + } + + VectorData vectorData = VectorData.builder(). + type(vectorMeta.getType()). + group(vectorMeta.getGroupTag()). + leaf(vectorDetail.getLeafTag()). + vector(detailDto.getVector()).build(); + vectorDataList.add(vectorData); + } + if (tagsCheckRst.getKey()){ + redisVectorService.updateVectorByLeaf(vectorDataList); + return Result.success(true); + } + return Result.fail(ExCodes.STATUS_BAD_REQUEST, tagsCheckRst.getValue()); + } + + private Integer insertOrGetMeta(VKnowledgeVectorMetaPo vectorMeta){ + QueryWrapper queryWrapper = QueryWrapper.create(). + eq("type", vectorMeta.getType()). + eq("tag1", vectorMeta.getTag1()). + eq("group_tag", vectorMeta.getGroupTag()); + List metas = metaMapper.selectListByQuery(queryWrapper); + if (CollectionUtils.isEmpty(metas)){ + log.info("empty meta db,{},{},{}", vectorMeta.getType(), vectorMeta.getTag1(), vectorMeta.getGroupTag()); + vectorMeta.setGmtCreate(new Date()); + vectorMeta.setGmtModified(new Date()); + metaMapper.insert(vectorMeta); + return vectorMeta.getId(); + } else { + if (metas.get(0).getDeleted() == 1){ + log.warn("meta is deleted. id:{}", metas.get(0).getId()); + return -1; + } + return metas.get(0).getId(); + } + } + + + @Transactional + @Override + public Result deleteKnowledgeVector(KnowledgeVectorDto param) { + Pair checkRst = checkKnowledgeVectorDto(param, "delete"); + if (!checkRst.getKey()) { + return Result.fail(ExCodes.STATUS_BAD_REQUEST, checkRst.getValue()); + } + + List knowledgeVectorDetailDtoList = param.getKnowledgeVectorDetailDtoList(); + KnowledgeTypeEnum typeEnum = KnowledgeTypeEnum.getEnumByTypeName(param.getType()); + + List vectorMetas = new ArrayList<>(); + for (KnowledgeVectorDetailDto detailDto : knowledgeVectorDetailDtoList) { + KnowledgeVectorDetailFullDto fullDto = vectorDtoTruncateService.getFullDto(detailDto, typeEnum); + + //删除leafTag + if (StringUtils.isNotBlank(fullDto.getLeafTag())){ + VKnowledgeVectorDetailPo vectorDetail = detailMapper.selectOneByQuery( + QueryWrapper.create().eq("type", param.getType()).eq("leaf_tag", fullDto.getLeafTag()) + ); + if (vectorDetail!=null){ + log.info("delete vectorDetail id:{}, count:{}", vectorDetail.getId(), detailMapper.deleteById(vectorDetail.getId())); + } + VectorData vectorData = VectorData.builder(). + type(fullDto.getType()). + group(fullDto.getGroupTag()) + .leaf(fullDto.getLeafTag()).build(); + boolean redisDel = redisVectorService.deleteByLeaf(Arrays.asList(vectorData)); + log.info("delete redis leaf group_leaf:{}, rst:{}", fullDto.getGroupTag()+"_"+fullDto.getLeafTag(), redisDel); + } + //删除单个groupTag + else if (StringUtils.isNotBlank(fullDto.getGroupTag())){ + VKnowledgeVectorMetaPo vectorMeta = metaMapper.selectOneByQuery( + QueryWrapper.create().eq("type", fullDto.getType()).eq("group_tag", fullDto.getGroupTag()).eq("deleted", 0) + ); + if (vectorMeta==null){ + log.warn("can not find groupTag:{}", fullDto.getGroupTag()); + continue; + } + vectorMetas.add(vectorMeta); + } else { + StringBuilder qryTags = new StringBuilder(detailDto.getTag1()); + //从meta表中查询所有符合条件的group + QueryWrapper queryWrapper = QueryWrapper.create(). + eq("type", fullDto.getType()). + eq("deleted", 0). + eq("tag1", detailDto.getTag1()); + if (StringUtils.isNotBlank(detailDto.getTag2())){ + queryWrapper.eq("tag2", detailDto.getTag2()); + qryTags.append("_"+detailDto.getTag2()); + } + if (StringUtils.isNotBlank(detailDto.getTag3())){ + queryWrapper.eq("tag3", detailDto.getTag3()); + qryTags.append("_"+detailDto.getTag3()); + } + if (StringUtils.isNotBlank(detailDto.getTag4())){ + queryWrapper.eq("tag4", detailDto.getTag4()); + qryTags.append("_"+detailDto.getTag4()); + } + + List metaList = metaMapper.selectListByQuery(queryWrapper); + if (CollectionUtils.isEmpty(metaList)){ + log.warn("can not find qryTags:{}", qryTags); + continue; + } + log.info("qryTags:{}, ids:{}", qryTags, metaList.stream().map(i ->i.getId()).collect(Collectors.toList())); + vectorMetas.addAll(metaList); + } + } + if (CollectionUtils.isEmpty(vectorMetas)){ + log.info("There is no vectorMetas to delete"); + return Result.success(true); + } + List metaIds = vectorMetas.stream().map(i -> i.getId()).collect(Collectors.toList()); + log.info("preparing to delete from db metaIds:{}", metaIds); + int detailCount = detailMapper.deleteByQuery(QueryWrapper.create().eq("type", param.getType()).in("meta_id", metaIds)); + int metaCount = param.isForceDelete() ? metaMapper.deleteBatchByIds(metaIds) : metaMapper.softDelete(metaIds); + log.info("delete from db detailCount:{},metaCount:{},isForceDelete:{}", detailCount, metaCount, param.isForceDelete()); + List groupKeyList = vectorMetas.stream().map(i -> VectorData.makeGroupKey(i.getType(), i.getGroupTag())).collect(Collectors.toList()); + log.info("delete from redis groupKeyList:{}, rst:{}", groupKeyList, redisVectorService.deleteByGroup(groupKeyList)); + return Result.success(true); + } + + + @Override + public Result> qrySimilarKnowledgeVector(SimilarKnowledgeVectorQry qry) { + Pair checkRst = checkSimilarKnowledgeVectorQry(qry); + if (!checkRst.getKey()) { + return Result.fail(ExCodes.STATUS_BAD_REQUEST, checkRst.getValue()); + } + + KnowledgeTypeEnum typeEnum = KnowledgeTypeEnum.getEnumByTypeName(qry.getType()); + + List vectorDataList = new ArrayList<>(); + + List tagsInfoList = qry.getTagsInfoList(); + + for (TagsInfo tagsInfo : tagsInfoList){ + TagsFullInfo fullQry = vectorDtoTruncateService.getSimilarKnowledgeVectorFullQry(tagsInfo, typeEnum); + //是否为leafTag范围的查询 + if (StringUtils.isNotBlank(fullQry.getLeafTag())){ + VKnowledgeVectorDetailPo vectorDetail = detailMapper.selectOneByQuery( + QueryWrapper.create().eq("type", qry.getType()).eq("leaf_tag", fullQry.getLeafTag()) + ); + if (vectorDetail==null){ + return Result.fail(ExCodes.STATUS_BAD_REQUEST, "Can't find leafTag[" + fullQry.getLeafTag() + "]"); + } + VKnowledgeVectorMetaPo vectorMeta = metaMapper.selectOneByQuery( QueryWrapper.create().eq("id", vectorDetail.getMetaId()).eq("deleted", 0)); + vectorDataList.add( + VectorData.builder(). + group(vectorMeta.getGroupTag()). + leaf(vectorDetail.getLeafTag()). + vector(gson.fromJson(vectorDetail.getVector(), new TypeToken() {}.getType())).build() + ); + + } //是否为单个groupTag的查询 + else if (StringUtils.isNotBlank(fullQry.getGroupTag())){ + VKnowledgeVectorMetaPo vectorMeta = metaMapper.selectOneByQuery( + QueryWrapper.create().eq("type", qry.getType()).eq("group_tag", fullQry.getGroupTag()).eq("deleted", 0) + ); + if (vectorMeta==null){ + log.warn("Can't find groupTag[{}]", fullQry.getGroupTag()); + continue; + } + log.info("db meta id:{},groupTag:{}", vectorMeta.getId(), vectorMeta.getGroupTag()); + vectorDataList.addAll(redisVectorService.listByGroup(Arrays.asList(VectorData.makeGroupKey(vectorMeta.getType(), vectorMeta.getGroupTag())))); + + } else { + StringBuilder qryTags = new StringBuilder(tagsInfo.getTag1()); + //从meta表中查询所有符合条件的group + QueryWrapper queryWrapper = QueryWrapper.create(). + eq("deleted", 0). + eq("type", qry.getType()). + eq("tag1", tagsInfo.getTag1()); + if (StringUtils.isNotBlank(tagsInfo.getTag2())){ + queryWrapper.eq("tag2", tagsInfo.getTag2()); + qryTags.append("_"+tagsInfo.getTag2()); + } + if (StringUtils.isNotBlank(tagsInfo.getTag3())){ + queryWrapper.eq("tag3", tagsInfo.getTag3()); + qryTags.append("_"+tagsInfo.getTag3()); + } + if (StringUtils.isNotBlank(tagsInfo.getTag4())){ + queryWrapper.eq("tag4", tagsInfo.getTag4()); + qryTags.append("_"+tagsInfo.getTag4()); + } + + List metaList = metaMapper.selectListByQuery(queryWrapper); + if (CollectionUtils.isEmpty(metaList)){ + log.warn("Can't find tag[{}]", qryTags); + continue; + } + List groupList = metaList.stream().map(i -> VectorData.makeGroupKey(i.getType(), i.getGroupTag())).collect(Collectors.toList()); + vectorDataList.addAll(redisVectorService.listByGroup(groupList)); + } + } + if (CollectionUtils.isEmpty(vectorDataList)){ + return Result.fail(ExCodes.STATUS_BAD_REQUEST, "Can't find any tag"); + } + log.info("qry from vectorDataList.size:{}", vectorDataList.size()); + + + //questionContent向量化 + double[] queryVector = StringUtils.isBlank(qry.getQuestionContent())?qry.getQuestionVector():embeddingService.getEmbeddingArr(qry.getQuestionContent()); + if (queryVector == null){ + return Result.fail(ExCodes.STATUS_INTERNAL_ERROR, "questionContent embedding error"); + } + + //cosineSimilarity + VectorLimits limits = VectorLimits.builder().similarity(qry.getSimilarity()).topN(qry.getTopN()).build(); + List topNData = ozVectorDbService.cosineSimilarity(queryVector, vectorDataList, limits); + + List rstList = topNData.stream().map(i -> + SimilarKnowledgeVectorRsp.builder().group(i.getGroup()).leaf(i.getLeaf()).similarity(i.getSimilarity()).build() + ).collect(Collectors.toList()); + + log.info("qryKnowledgeVector rst:{}", rstList); + return Result.success(rstList); + } + + + private Pair checkSimilarKnowledgeVectorQry(SimilarKnowledgeVectorQry param) { + if (null == param || CollectionUtils.isEmpty(param.getTagsInfoList())) { + return Pair.of(false, "param is invalid"); + } + if (!KnowledgeTypeEnum.isEnumValueValid(param.getType())) { + return Pair.of(false, "type is invalid"); + } + if (null == param.getQuestionVector() && StringUtils.isBlank(param.getQuestionContent())) { + return Pair.of(false, "question is empty"); + } + List tagsInfoList = param.getTagsInfoList(); + for (TagsInfo tagsInfo : tagsInfoList){ + if (null == tagsInfo || StringUtils.isBlank(tagsInfo.getTag1())){ + return Pair.of(false, "tagsInfoList is invalid"); + } + } + return Pair.of(true, ""); + } + + private Pair checkKnowledgeVectorDto(KnowledgeVectorDto param, String operateType) { + if (null == param || CollectionUtils.isEmpty(param.getKnowledgeVectorDetailDtoList())) { + return Pair.of(false, "param is empty"); + } + + if (!KnowledgeTypeEnum.isEnumValueValid(param.getType())) { + return Pair.of(false, "type is invalid"); + } + List knowledgeVectorDetailDtoList = param.getKnowledgeVectorDetailDtoList(); + + for (KnowledgeVectorDetailDto detailDto : knowledgeVectorDetailDtoList){ + if (StringUtils.isBlank(detailDto.getTag1())){ + return Pair.of(false, "tag1 is empty"); + } + if ("insertOrUpdate".equals(operateType)){ + if (param.isNeedEmbedding() && StringUtils.isBlank(detailDto.getContent())){ + return Pair.of(false, "content is empty"); + } + if (!param.isNeedEmbedding() && null == detailDto.getVector()){ + return Pair.of(false, "vector is empty"); + } + } + } + return Pair.of(true, ""); + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/resources/application.properties b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/application.properties new file mode 100644 index 000000000..3bde886d4 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/application.properties @@ -0,0 +1,23 @@ +#server +app.name=@app.name@ +server.type=@server.type@ +server.port=@server.port@ +server.debug=@server.debug@ + +dubbo.group=@dubbo.group@ +dubbo.protocol.port=@dubbo.protocol.port@ +dubbo.registry.address=@dubbo.registry.address@ +nacos.config.addrs=@nacos.config.addrs@ + +log.path=@log.path@ + +db_url=@db_url@ +db_user_name=@db_user_name@ +db_pwd=@db_pwd@ + +# redis info +spring.redis=@spring.redis@ +redis.cluster.pwd=@redis.cluster.pwd@ +redis.cluster=@redis.cluster@ + +token.server=@token.server@ \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/dev.properties b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/dev.properties new file mode 100644 index 000000000..ee8ba1f43 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/dev.properties @@ -0,0 +1,23 @@ +#server +app.name=private-knowledge +server.type=dev +server.port=8083 +server.debug=true + +dubbo.group=dev +dubbo.protocol.port=-1 +dubbo.registry.address=nacos://localhost:80 +nacos.config.addrs=localhost:80 + +log.path=/tmp + +db_url=jdbc:mysql://localhost:13306/mione_z?characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true&useServerPrepStmts=false&rewriteBatchedStatements=true +db_user_name=X +db_pwd=X + +# redis info +spring.redis=localhost:22122 +redis.cluster.pwd=X +redis.cluster=false + +token.server=http://localhost:80 \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/online.properties b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/online.properties new file mode 100644 index 000000000..50bea1c80 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/online.properties @@ -0,0 +1,23 @@ +#server +app.name=private-knowledge +server.type=online +server.port=8083 +server.debug=true + +dubbo.group=online +dubbo.protocol.port=-1 +dubbo.registry.address=nacos://localhost:80 +nacos.config.addrs=localhost:80 + +log.path=/home/work/log + +db_url=jdbc:mysql://localhost:63306/mione_knowledge?characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&serverTimezone=UTC +db_user_name=X +db_pwd=X + +# redis info +spring.redis=localhost:5100 +redis.cluster.pwd=X +redis.cluster=true + +token.server=http://localhost:80 \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/staging.properties b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/staging.properties new file mode 100644 index 000000000..53ad87a69 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/config/staging.properties @@ -0,0 +1,23 @@ +#server +app.name=private-knowledge +server.type=staging +server.port=8083 +server.debug=true + +dubbo.group=staging +dubbo.protocol.port=-1 +dubbo.registry.address=nacos://localhostv:80 +nacos.config.addrs=localhost:80 + +log.path=/home/work/log + +db_url=jdbc:mysql://localhost:13306/mione_z?characterEncoding=utf8&autoReconnect=true&failOverReadOnly=false&serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true&useServerPrepStmts=false&rewriteBatchedStatements=true +db_user_name=X +db_pwd=X + +# redis info +spring.redis=localhost:22122 +redis.cluster.pwd=X +redis.cluster=false + +token.server=http://localhost:80 \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/resources/dubbo.properties b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/dubbo.properties new file mode 100644 index 000000000..260d5cd2b --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/dubbo.properties @@ -0,0 +1 @@ +dubbo.trace.log.path=/home/work/log/dubbo/private-knowledge_ diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/resources/logback.xml b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/logback.xml new file mode 100644 index 000000000..9538d657e --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/logback.xml @@ -0,0 +1,59 @@ + + + + + + + + + ${log.path}/private-knowledge/server.log + + %d|%-5level|%X{trace_id}|%thread|%logger{40}|%msg%n + + + ${log.path}/private-knowledge/server.log.%d{yyyy-MM-dd-HH} + ${MAX_HISTORY} + + + + + 0 + 60000 + + + + + + ${log.path}/private-knowledge/error.log + + %d|%-5level|%X{trace_id}|%thread|%logger{40}|%msg%n + + + ${log.path}/private-knowledge/error.log.%d{yyyy-MM-dd-HH} + ${MAX_HISTORY} + + + ERROR + ACCEPT + DENY + + + + + + %d|%-5level|%X{trace_id}|%thread|%logger{40}|%msg%n + + + + + + + + + + + + + + + diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/resources/sql/20240612.sql b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/sql/20240612.sql new file mode 100644 index 000000000..18337a7f5 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/sql/20240612.sql @@ -0,0 +1,3 @@ +ALTER TABLE v_knowledge_vector_meta ADD COLUMN `gmt_create` datetime DEFAULT NULL COMMENT '创建时间'; +ALTER TABLE v_knowledge_vector_meta ADD COLUMN `gmt_modified` datetime DEFAULT NULL COMMENT '修改时间'; +ALTER TABLE v_knowledge_vector_meta ADD COLUMN `deleted` int(1) DEFAULT 0 COMMENT '0:未删除 1:已删除'; diff --git a/m78-all/private-knowledge/private-knowledge-server/src/main/resources/sql/init.sql b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/sql/init.sql new file mode 100644 index 000000000..ab70499be --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/main/resources/sql/init.sql @@ -0,0 +1,30 @@ +CREATE TABLE `v_knowledge_vector_meta` ( + `id` int NOT NULL AUTO_INCREMENT primary key, + `type` varchar(64) DEFAULT NULL COMMENT '知识库类型,normal_document、project_code', + `tag1` varchar(64) NOT NULL COMMENT 'tag1', + `tag2` varchar(64) DEFAULT '' COMMENT 'tag2', + `tag3` varchar(64) DEFAULT '' COMMENT 'tag3', + `tag4` varchar(64) DEFAULT '' COMMENT 'tag4', + `tag5` varchar(64) DEFAULT '' COMMENT 'tag5', + `tag6` varchar(64) DEFAULT '' COMMENT 'tag6', + `group_tag` varchar(64) NOT NULL COMMENT 'group节点tag', + INDEX (type, tag1, tag2, tag3, tag4, tag5, tag6), + INDEX type_group_tag_index (type, group_tag), + UNIQUE KEY type_group_tag_unique (type, group_tag) +) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT='知识库向量元数据,仅存储至group节点级别(除leaf层级外,最多支持六层tag结构)'; + + +CREATE TABLE `v_knowledge_vector_detail` ( + `id` int NOT NULL AUTO_INCREMENT primary key, + `meta_id` int NOT NULL COMMENT 'v_knowledge_vector_meta的id', + `gmt_create` datetime DEFAULT NULL COMMENT '创建时间', + `gmt_modified` datetime DEFAULT NULL COMMENT '修改时间', + `type` varchar(64) DEFAULT NULL COMMENT '知识库类型,normal_document、project_code', + `leaf_tag` varchar(64) NOT NULL COMMENT '叶子节点tag', + `content` text DEFAULT NULL COMMENT '区块/文件内容', + `embedding_status` int(11) NOT NULL DEFAULT '0' COMMENT '向量化状态0:未开始, 1:进行中, 2:已完成', + `vector` blob NOT NULL, + FOREIGN KEY (meta_id) REFERENCES v_knowledge_vector_meta (id), + INDEX type_leaf_tag_index (type, leaf_tag), + UNIQUE KEY type_leaf_tag_unique (type, leaf_tag) +) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT='知识库向量详情,仅存储叶子节点'; diff --git a/m78-all/private-knowledge/private-knowledge-server/src/test/java/run/mone/test/DbCodegen.java b/m78-all/private-knowledge/private-knowledge-server/src/test/java/run/mone/test/DbCodegen.java new file mode 100644 index 000000000..8f9b749d6 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/test/java/run/mone/test/DbCodegen.java @@ -0,0 +1,76 @@ +package run.mone.test; + +import com.mybatisflex.codegen.Generator; +import com.mybatisflex.codegen.config.ColumnConfig; +import com.mybatisflex.codegen.config.GlobalConfig; +import com.mybatisflex.codegen.config.TableDefConfig; +import com.zaxxer.hikari.HikariDataSource; + + +/** + * @author wmin + * @date 2024/2/2 + */ +public class DbCodegen { + + private static String tableName = ""; + + public static void main(String[] args) { + //配置数据源 + HikariDataSource dataSource = new HikariDataSource(); + dataSource.setJdbcUrl("jdbc:mysql://localhost:13306/mione_z?characterEncoding=utf-8"); + dataSource.setUsername("X"); + dataSource.setPassword("X"); + + //创建配置内容,两种风格都可以。 + GlobalConfig globalConfig = createGlobalConfigUseStyle1(); + //GlobalConfig globalConfig = createGlobalConfigUseStyle2(); + + //通过 datasource 和 globalConfig 创建代码生成器 + Generator generator = new Generator(dataSource, globalConfig); + + //生成代码 + generator.generate(); + } + + public static GlobalConfig createGlobalConfigUseStyle1() { + //创建配置内容 + GlobalConfig globalConfig = new GlobalConfig(); + + //设置根包 + globalConfig.setBasePackage("run.mone.knowledge.service.dao"); + + //设置表前缀和只生成哪些表 + globalConfig.setGenerateTable("v_knowledge_vector_detail", "v_knowledge_vector_meta"); + + //设置生成 entity 并启用 Lombok + globalConfig.setEntityGenerateEnable(true); + globalConfig.setEntityWithLombok(true); + //设置项目的JDK版本,项目的JDK为14及以上时建议设置该项,小于14则可以不设置 + //globalConfig.setJdkVersion(17); + + //设置生成 mapper + globalConfig.setMapperGenerateEnable(true); + + String dir = "/Users/wmin/Documents/xiaomi-project/private-knowledge/private-knowledge-service/src/main/java"; +// String dir = "/Users/zhangzhiyong/IdeaProjects/ai/m78/m78-service/src/main/java"; + + globalConfig.getEntityConfig().setSourceDir(dir); + globalConfig.getMapperConfig().setSourceDir(dir); + + + //可以单独配置某个列 +// ColumnConfig columnConfig = new ColumnConfig(); +// columnConfig.setColumnName("tenant_id"); +// columnConfig.setLarge(true); +// columnConfig.setVersion(true); +// globalConfig.setColumnConfig("tb_account", columnConfig); + +// TableDefConfig tableDefConfig = new TableDefConfig(); +// tableDefConfig.setClassPrefix("KnowledgeVector"); + globalConfig.getTableDefConfig().setClassPrefix("KnowledgeVector"); + return globalConfig; + } + + +} diff --git a/m78-all/private-knowledge/private-knowledge-server/src/test/java/run/mone/test/VectorProviderTest.java b/m78-all/private-knowledge/private-knowledge-server/src/test/java/run/mone/test/VectorProviderTest.java new file mode 100644 index 000000000..3fda36171 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-server/src/test/java/run/mone/test/VectorProviderTest.java @@ -0,0 +1,84 @@ +package run.mone.test; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import run.mone.knowledge.api.IKnowledgeVectorProvider; +import run.mone.knowledge.api.dto.VectorData; +import run.mone.knowledge.api.enums.KnowledgeTypeEnum; +import run.mone.knowledge.api.dto.KnowledgeVectorDetailDto; +import run.mone.knowledge.api.dto.KnowledgeVectorDto; +import run.mone.knowledge.api.dto.SimilarKnowledgeVectorQry; +import run.mone.knowledge.server.PrivateKnowledgeBootstrap; +import run.mone.knowledge.service.RedisVectorService; + +import javax.annotation.Resource; +import java.util.Arrays; + +/** + * @author wmin + * @date 2024/2/19 + */ +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = PrivateKnowledgeBootstrap.class) +public class VectorProviderTest { + @Resource + private IKnowledgeVectorProvider knowledgeVectorProvider; + + @Autowired + private RedisVectorService redisVectorService; + + @Test + public void getGroupFromRedis() { + System.out.println(redisVectorService.listByGroup(Arrays.asList(VectorData.makeGroupKey(KnowledgeTypeEnum.project_code.getTypeName(),"tag21"), + VectorData.makeGroupKey(KnowledgeTypeEnum.project_code.getTypeName(),"tag22")))); + } + + @Test + public void insertKnowledgeVector() { + KnowledgeVectorDto param = new KnowledgeVectorDto(); + param.setType(KnowledgeTypeEnum.project_code.getTypeName()); + KnowledgeVectorDetailDto detailDto = new KnowledgeVectorDetailDto(); + detailDto.setTag1("tag1"); + detailDto.setTag2("tag21"); + detailDto.setTag3("tag31"); + detailDto.setContent("tomato-番茄"); + KnowledgeVectorDetailDto detailDto2 = new KnowledgeVectorDetailDto(); + detailDto2.setTag1("tag1"); + detailDto2.setTag2("tag22"); + detailDto2.setTag3("tag32"); + detailDto2.setContent("banana香蕉"); + param.setKnowledgeVectorDetailDtoList(Arrays.asList(detailDto, detailDto2)); + System.out.println(knowledgeVectorProvider.insertOrUpdateKnowledgeVector(param)); + } + + @Test + public void deleteKnowledgeVector() { + KnowledgeVectorDto param = new KnowledgeVectorDto(); + param.setType(KnowledgeTypeEnum.project_code.getTypeName()); + KnowledgeVectorDetailDto detailDto = new KnowledgeVectorDetailDto(); + detailDto.setTag1("tag1"); + detailDto.setTag2("tag21"); + detailDto.setTag3("tag31"); +// KnowledgeVectorDetailDto detailDto2 = new KnowledgeVectorDetailDto(); +// detailDto2.setTag1("tag1"); +// detailDto2.setTag2("tag22"); +// detailDto2.setTag3("tag32"); + param.setKnowledgeVectorDetailDtoList(Arrays.asList(detailDto)); + System.out.println(knowledgeVectorProvider.deleteKnowledgeVector(param)); + } + + @Test + public void qrySimilarKnowledgeVector() { + SimilarKnowledgeVectorQry param = new SimilarKnowledgeVectorQry(); + param.setType(KnowledgeTypeEnum.project_code.getTypeName()); + //param.setTag1("tag1"); + //param.setTag2("tag22"); + //param.setTag3("tag32"); + param.setQuestionContent("banana"); + System.out.println(knowledgeVectorProvider.qrySimilarKnowledgeVector(param)); + } +} + diff --git a/m78-all/private-knowledge/private-knowledge-service/pom.xml b/m78-all/private-knowledge/private-knowledge-service/pom.xml new file mode 100644 index 000000000..765777a24 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/pom.xml @@ -0,0 +1,79 @@ + + + + private-knowledge + run.mone.privateknowledge + 1.0-SNAPSHOT-SNAPSHOT + + 4.0.0 + + private-knowledge-service + + + + + private-knowledge-api + run.mone.privateknowledge + 1.0-SNAPSHOT-SNAPSHOT + + + org.apache.dubbo + dubbo + + + org.springframework.boot + spring-boot-starter-web + + + + private-knowledge-common + run.mone.privateknowledge + 1.0-SNAPSHOT-SNAPSHOT + + + com.alibaba.nacos + nacos-api + + + mysql + mysql-connector-java + + + org.springframework.boot + spring-boot-starter-jdbc + + + com.mybatis-flex + mybatis-flex-spring-boot-starter + + + com.mybatis-flex + mybatis-flex-codegen + + + run.mone + redis + 1.8-inner-SNAPSHOT + + + org.apache.commons + commons-math3 + + + com.alibaba.fastjson2 + fastjson2 + 2.0.26 + + + + run.mone + http + 1.4-SNAPSHOT + + + + + + \ No newline at end of file diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/DemoService.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/DemoService.java new file mode 100644 index 000000000..0eccf4ac0 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/DemoService.java @@ -0,0 +1,29 @@ +package run.mone.knowledge.service; + +import run.mone.knowledge.api.dto.DemoReqDto; +import run.mone.knowledge.api.dto.DemoResDto; +import run.mone.knowledge.service.dao.DemoDao; +import run.mone.knowledge.service.dao.entity.DemoEntity; +import run.mone.knowledge.service.rpc.DemoDepRpc; +import run.mone.knowledge.service.rpc.dto.DemoDepReqDto; +import run.mone.knowledge.service.rpc.dto.DemoDepResDto; +import com.xiaomi.youpin.infra.rpc.Result; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DemoService { + + @Autowired + private DemoDepRpc demoDepRpc; + @Autowired + private DemoDao demoDao; + + public Result query(DemoReqDto reqDto) { + //rpc远程调用 + DemoDepResDto rpcResDto = demoDepRpc.remoteReq(DemoDepReqDto.build(reqDto)); + //持久化实体查询 + DemoEntity entity = demoDao.getById(reqDto.getId()); + return Result.success(entity.buildDemoResDto(rpcResDto)); + } +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/EmbeddingService.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/EmbeddingService.java new file mode 100644 index 000000000..9cbd11516 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/EmbeddingService.java @@ -0,0 +1,55 @@ +package run.mone.knowledge.service; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.xiaomi.data.push.client.HttpClientV2; +import com.xiaomi.youpin.infra.rpc.Result; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import run.mone.knowledge.service.exceptions.ExCodes; + +import java.util.*; + +/** + * @author wmin + * @date 2024/2/6 + */ +@Service +@Slf4j +public class EmbeddingService { + + public static Gson gson = new Gson(); + + @Value("${token.server}") + private String tokenServer; + + public String getEmbeddingStr(String input) { + try { + Map headers = new HashMap<>(); + headers.put("content-type", "application/json"); + Map post = new HashMap<>(); + post.put("data", input); + return HttpClientV2.post(String.format("%s/embedding", tokenServer), gson.toJson(post), headers, 100000); + } catch (Exception e) { + log.error("getEmbedding error {}", e); + return null; + } + } + + public double[] getEmbeddingArr(String input) { + try { + String inputEmbedding = getEmbeddingStr(input); + if (StringUtils.isBlank(inputEmbedding)){ + log.error("http call error"); + return null; + } + return gson.fromJson(inputEmbedding, new TypeToken() {}.getType()); + } catch (Exception e) { + log.error("getEmbedding error {}", e); + return null; + } + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/OzVectorDbService.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/OzVectorDbService.java new file mode 100644 index 000000000..14e8682a9 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/OzVectorDbService.java @@ -0,0 +1,42 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 run.mone.knowledge.service; + +import run.mone.knowledge.api.dto.VectorData; +import run.mone.knowledge.api.dto.VectorLimits; + +import java.util.List; + +/** + * @author shanwb + * @date 2024-02-06 + */ +public interface OzVectorDbService { + + /** + * 查找topN 相似向量结果 + * + * @param queryVector + * @param vectorDataList + * @param limits + * @return + */ + List cosineSimilarity(double[] queryVector, List vectorDataList, VectorLimits limits); + + + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/RedisVectorService.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/RedisVectorService.java new file mode 100644 index 000000000..78b05e79c --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/RedisVectorService.java @@ -0,0 +1,68 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 run.mone.knowledge.service; + +import run.mone.knowledge.api.dto.VectorData; + +import java.util.List; +import java.util.Map; + +/** + * @author shanwb + * @date 2024-02-06 + */ +public interface RedisVectorService { + String SPLIT_CHAR = "_#_"; + + /** + * 存储向量化结果,注意会按group进行全量覆盖,确保传递的是group下的全量数据 + * + * @param vectorDataList + * @return + */ + boolean storeVectorByGroup(List vectorDataList); + + /** + * 按叶子节点进行向量更新 + * + * @param vectorDataList + * @return + */ + boolean updateVectorByLeaf(List vectorDataList); + + /** + * 按group查询所有向量结果 + * + * @param groupKeyList + * @return + */ + List listByGroup(List groupKeyList); + + + /** + * 生成一个映射,其键是字符串,值是另一个映射,该映射的键是字符串,值是双精度数组,根据提供的分组列表进行组织。 + */ + Map> listByGroup2(List groupKeyList); + + boolean deleteByGroup(List groupKeyList); + + boolean deleteByLeaf(List vectorDataList); + + + + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/common/CommonUtils.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/common/CommonUtils.java new file mode 100644 index 000000000..cf1b02ecf --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/common/CommonUtils.java @@ -0,0 +1,25 @@ +package run.mone.knowledge.service.common; + +/** + * @author wmin + * @date 2024/2/6 + */ +public class CommonUtils { + + /** + * 将字符串转为double数组 + * @param str [1.2,3.2] + * @return + */ + public static double[] parseDoubleArray(String str) { + // 移除首尾的方括号并使用逗号分割字符串 + String[] parts = str.substring(1, str.length() - 1).split(","); + double[] result = new double[parts.length]; + for (int i = 0; i < parts.length; i++) { + // 将每个字符串转换为 double 类型 + result[i] = Double.parseDouble(parts[i]); + } + return result; + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/DemoDao.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/DemoDao.java new file mode 100644 index 000000000..bea81f919 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/DemoDao.java @@ -0,0 +1,13 @@ +package run.mone.knowledge.service.dao; + +import run.mone.knowledge.service.dao.entity.DemoEntity; +import org.springframework.stereotype.Repository; + +@Repository +public class DemoDao { + + public DemoEntity getById(Long id) { + return DemoEntity.build(); + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/DemoEntity.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/DemoEntity.java new file mode 100644 index 000000000..e322f927a --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/DemoEntity.java @@ -0,0 +1,27 @@ +package run.mone.knowledge.service.dao.entity; + +import run.mone.knowledge.api.dto.DemoResDto; +import run.mone.knowledge.service.rpc.dto.DemoDepResDto; +import lombok.Data; +import lombok.ToString; + +@Data +@ToString +public class DemoEntity { + + private String test2; + + public DemoResDto buildDemoResDto(DemoDepResDto rpcResDto) { + DemoResDto dto = new DemoResDto(); + dto.setTest1(rpcResDto.getTest1()); + dto.setTest2(test2); + return dto; + } + + public static DemoEntity build() { + DemoEntity entity = new DemoEntity(); + entity.test2 = "hello world"; + return entity; + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/M78Test.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/M78Test.java new file mode 100644 index 000000000..67a3b9cf6 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/M78Test.java @@ -0,0 +1,60 @@ +package run.mone.knowledge.service.dao.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.math.BigInteger; +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 实体类。 + * + * @author wmin + * @since 2024-02-04 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(value = "m78_test") +public class M78Test implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @Id(keyType = KeyType.Auto) + private BigInteger id; + + /** + * 创建时间 + */ + private LocalDateTime gmtCreate; + + /** + * 创建者 + */ + private String creator; + + /** + * 原文本 + */ + private String textBefore; + + /** + * 脱敏后文本 + */ + private String textAfter; + + /** + * 状态, 0: 失败, 1:成功 + */ + private Integer status; + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/VKnowledgeVectorDetailPo.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/VKnowledgeVectorDetailPo.java new file mode 100644 index 000000000..23ef84dac --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/VKnowledgeVectorDetailPo.java @@ -0,0 +1,66 @@ +package run.mone.knowledge.service.dao.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.util.Date; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 实体类。 + * + * @author wmin + * @since 2024-02-19 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(value = "v_knowledge_vector_detail") +public class VKnowledgeVectorDetailPo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @Id(keyType = KeyType.Auto) + private Integer id; + + private Integer metaId; + + private String type; + + /** + * 创建时间 + */ + private Date gmtCreate; + + /** + * 修改时间 + */ + private Date gmtModified; + + /** + * 叶子节点tag + */ + private String leafTag; + + /** + * 区块/文件内容 + */ + private String content; + + /** + * 向量化状态0:未开始, 1:进行中, 2:已完成 + */ + private Integer embeddingStatus; + + private String vector; + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/VKnowledgeVectorMetaPo.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/VKnowledgeVectorMetaPo.java new file mode 100644 index 000000000..312f042bf --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/entity/VKnowledgeVectorMetaPo.java @@ -0,0 +1,87 @@ +package run.mone.knowledge.service.dao.entity; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import java.io.Serializable; +import java.util.Date; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 实体类。 + * + * @author wmin + * @since 2024-02-19 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(value = "v_knowledge_vector_meta") +public class VKnowledgeVectorMetaPo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @Id(keyType = KeyType.Auto) + private Integer id; + + private String type; + + /** + * tag1 + */ + private String tag1; + + /** + * tag2 + */ + private String tag2; + + /** + * tag3 + */ + private String tag3; + + /** + * tag4 + */ + private String tag4; + + /** + * tag5 + */ + private String tag5; + + /** + * tag6 + */ + private String tag6; + + /** + * group节点tag + */ + private String groupTag; + + /** + * 创建时间 + */ + private Date gmtCreate; + + /** + * 修改时间 + */ + private Date gmtModified; + + /** + * 0:未删除 1:已删除 + */ + private int deleted; + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/M78TestMapper.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/M78TestMapper.java new file mode 100644 index 000000000..7577c8822 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/M78TestMapper.java @@ -0,0 +1,14 @@ +package run.mone.knowledge.service.dao.mapper; + +import com.mybatisflex.core.BaseMapper; +import run.mone.knowledge.service.dao.entity.M78Test; + +/** + * 映射层。 + * + * @author wmin + * @since 2024-02-04 + */ +public interface M78TestMapper extends BaseMapper { + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/VKnowledgeVectorDetailMapper.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/VKnowledgeVectorDetailMapper.java new file mode 100644 index 000000000..e9c89eecb --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/VKnowledgeVectorDetailMapper.java @@ -0,0 +1,14 @@ +package run.mone.knowledge.service.dao.mapper; + +import com.mybatisflex.core.BaseMapper; +import run.mone.knowledge.service.dao.entity.VKnowledgeVectorDetailPo; + +/** + * 映射层。 + * + * @author wmin + * @since 2024-02-19 + */ +public interface VKnowledgeVectorDetailMapper extends BaseMapper { + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/VKnowledgeVectorMetaMapper.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/VKnowledgeVectorMetaMapper.java new file mode 100644 index 000000000..14f06de58 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/dao/mapper/VKnowledgeVectorMetaMapper.java @@ -0,0 +1,28 @@ +package run.mone.knowledge.service.dao.mapper; + +import com.mybatisflex.core.BaseMapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; +import run.mone.knowledge.service.dao.entity.VKnowledgeVectorMetaPo; + +import java.util.List; + +/** + * 映射层。 + * + * @author wmin + * @since 2024-02-19 + */ +public interface VKnowledgeVectorMetaMapper extends BaseMapper { + + @Update({ + "" + }) + int softDelete(@Param("ids") List ids); + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/exceptions/ExCodes.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/exceptions/ExCodes.java new file mode 100644 index 000000000..b6531aed6 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/exceptions/ExCodes.java @@ -0,0 +1,31 @@ +package run.mone.knowledge.service.exceptions; + +import com.xiaomi.youpin.infra.rpc.errors.ErrorCode; +import com.xiaomi.youpin.infra.rpc.errors.ErrorScope; + +/** + * @author HawickMason@xiaomi.com + * @date 1/11/24 11:20 + */ +public class ExCodes { + + + public static final ErrorScope DEFAULT_ERROR_SCOPE = ErrorScope.createOnce(0); + public static final ErrorCode STATUS_FORBIDDEN = ErrorCode.createOnce(DEFAULT_ERROR_SCOPE, 403); + + public static final ErrorCode STATUS_CONFLICT = ErrorCode.createOnce(DEFAULT_ERROR_SCOPE, 409); + + public static final ErrorCode STATUS_TOO_MANY_REQUESTS = ErrorCode.createOnce(DEFAULT_ERROR_SCOPE, 429); + + public static final ErrorCode STATUS_INTERNAL_ERROR = ErrorCode.createOnce(DEFAULT_ERROR_SCOPE, 500); + + public static final ErrorCode STATUS_INNER_QUERY_ERROR = ErrorCode.createOnce(DEFAULT_ERROR_SCOPE, 600); + + public static final ErrorCode STATUS_BAD_REQUEST = ErrorCode.createOnce(DEFAULT_ERROR_SCOPE, 400); + + public static final ErrorCode STATUS_METHOD_NOT_ALLOWED = ErrorCode.createOnce(DEFAULT_ERROR_SCOPE, 405); + + public static final ErrorCode STATUS_NOT_FOUND = ErrorCode.createOnce(DEFAULT_ERROR_SCOPE, 404); + + public static final ErrorCode STATUS_INVALID_ARGUMENT = ErrorCode.createOnce(DEFAULT_ERROR_SCOPE, 408); +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/OzVectorDbServiceImpl.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/OzVectorDbServiceImpl.java new file mode 100644 index 000000000..e8120ebe8 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/OzVectorDbServiceImpl.java @@ -0,0 +1,63 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 run.mone.knowledge.service.impl; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.math3.linear.ArrayRealVector; +import org.apache.commons.math3.linear.RealVector; +import org.springframework.stereotype.Service; +import run.mone.knowledge.api.dto.VectorData; +import run.mone.knowledge.api.dto.VectorLimits; +import run.mone.knowledge.service.OzVectorDbService; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author shanwb + * @date 2024-02-06 + */ +@Service +@Slf4j +public class OzVectorDbServiceImpl implements OzVectorDbService { + + @Override + public List cosineSimilarity(double[] queryVector, List vectorDataList, VectorLimits limits) { + List topVectorList = vectorDataList.parallelStream().map(v -> { + double similarity = cosineSimilarity(queryVector, v.getVector()); + v.setSimilarity(similarity); + return v; + }).filter(v -> { + if (null != limits.getSimilarity()) { + return v.getSimilarity() > limits.getSimilarity(); + } + return true; + }).sorted(Comparator.comparingDouble(VectorData::getSimilarity).reversed()) + .limit(null == limits.getRealTopN() ? Long.MAX_VALUE : limits.getRealTopN()) + .collect(Collectors.toList()); + + return topVectorList; + } + + public static double cosineSimilarity(double[] vectorA, double[] vectorB) { + RealVector a = new ArrayRealVector(vectorA); + RealVector b = new ArrayRealVector(vectorB); + return a.cosine(b); + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/RedisVectorServiceImpl.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/RedisVectorServiceImpl.java new file mode 100644 index 000000000..eff908187 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/RedisVectorServiceImpl.java @@ -0,0 +1,229 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 run.mone.knowledge.service.impl; + +import com.google.common.collect.Lists; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.xiaomi.data.push.redis.Redis; +import org.apache.commons.lang3.tuple.Pair; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import run.mone.knowledge.api.dto.VectorData; +import run.mone.knowledge.service.RedisVectorService; + +import java.lang.reflect.Type; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author shanwb + * @date 2024-02-06 + */ +@Service +@Slf4j +public class RedisVectorServiceImpl implements RedisVectorService { + @Autowired + private Redis redis; + + private Gson gson = new Gson(); + + private static Type typeOfT = new TypeToken>() { + }.getType(); + + + //将List vectorDataList 转换为Map> dataMap 并存入redis (class) + @Override + public boolean storeVectorByGroup(List vectorDataList) { + Map> dataMap = new HashMap<>(); + + for (VectorData vectorData : vectorDataList) { + String outerKey = vectorData.getGroupKey(); + String innerKey = vectorData.getLeaf(); + double[] values = vectorData.getVector(); + + if (!dataMap.containsKey(outerKey)) { + dataMap.put(outerKey, new HashMap<>()); + } + + dataMap.get(outerKey).put(innerKey, values); + } + + for (Map.Entry> entry : dataMap.entrySet()) { + String groupKey = entry.getKey(); + Map data = entry.getValue(); + String jsonData = gson.toJson(data); + + redis.set(groupKey, jsonData); + } + + return true; + } + + /** + * 更新向量结果 + * + * @param vectorDataList 向量数据列表 + * @return 是否更新成功 + */ + @Override + public boolean updateVectorByLeaf(List vectorDataList) { + Map> dataMap = new HashMap<>(); + + for (VectorData vectorData : vectorDataList) { + String outerKey = vectorData.getGroupKey(); + String innerKey = vectorData.getLeaf(); + double[] values = vectorData.getVector(); + + if (!dataMap.containsKey(outerKey)) { + dataMap.put(outerKey, new HashMap<>()); + } + + dataMap.get(outerKey).put(innerKey, values); + } + + //查询已存在向量结果 + Map> existsDataMap = listByGroup2(new ArrayList<>(dataMap.keySet())); + + //更新向量结果 + for (Map.Entry> entry : dataMap.entrySet()) { + String groupKey = entry.getKey(); + Map updateData = entry.getValue(); + Map existsData = existsDataMap.get(groupKey); + if (null != existsData) { + existsData.putAll(updateData); + } else { + existsDataMap.put(groupKey, updateData); + } + } + + //更新回redis + for (Map.Entry> entry : existsDataMap.entrySet()) { + String groupKey = entry.getKey(); + Map data = entry.getValue(); + String jsonData = gson.toJson(data); + + redis.set(groupKey, jsonData); + } + + return true; + } + + @Override + public List listByGroup(List groupKeyList) { + List vectorDataList = new ArrayList<>(); + Map groupListResult = redis.mget(groupKeyList); + if (null == groupListResult) { + return Lists.newArrayList(); + } + + for (Map.Entry entry : groupListResult.entrySet()) { + String groupKey = entry.getKey(); + Pair pair = VectorData.parseGroupKey(groupKey); + String value = entry.getValue(); + + Map map = gson.fromJson(value, typeOfT); + if (null == map || map.isEmpty()){ + continue; + } + for (Map.Entry en : map.entrySet()) { + VectorData vectorData = new VectorData(); + vectorData.setType(pair.getKey()); + vectorData.setGroup(pair.getValue()); + vectorData.setLeaf(en.getKey()); + vectorData.setVector(en.getValue()); + + vectorDataList.add(vectorData); + } + } + + return vectorDataList; + } + + /** + * 根据提供的分组列表从Redis中获取数据,将每个分组的JSON字符串转换为Map并返回一个嵌套的Map结构。 + */ + @Override + public Map> listByGroup2(List groupKeyList) { + Map> resultMap = new HashMap<>(); + Map groupListResult = redis.mget(groupKeyList); + if (null == groupListResult) { + return resultMap; + } + + for (Map.Entry entry : groupListResult.entrySet()) { + String groupKey = entry.getKey(); + String value = entry.getValue(); + + Map map = gson.fromJson(value, typeOfT); + resultMap.put(groupKey, map); + } + + return resultMap; + } + + //基于VectorData的group列表进行redis数据删除,入参是List groupList (class) + @Override + public boolean deleteByGroup(List groupKeyList) { + for (String groupKey : groupKeyList) { + redis.del(groupKey); + } + return true; + } + + //基于VectorData的leaf列表进行redis数据删除,需要基于入参聚合出group集合,然后从redis中查出数据,并基于leaf进行数据删除,入参是List vectorDataList (class) + @Override + public boolean deleteByLeaf(List vectorDataList) { + // 聚合出group集合 + Set groupKeySet = vectorDataList.stream() + .map(VectorData::getGroupKey) + .collect(Collectors.toSet()); + + // 从redis中查出数据 + Map> groupDataMap = listByGroup2(new ArrayList<>(groupKeySet)); + + // 基于leaf进行数据删除 + vectorDataList.forEach(vectorData -> { + String groupKey = vectorData.getGroupKey(); + String leaf = vectorData.getLeaf(); + Map leafMap = groupDataMap.get(groupKey); + if (leafMap != null) { + leafMap.remove(leaf); + } + }); + + // 更新回redis + groupDataMap.forEach((groupKey, leafMap) -> { + if (null==leafMap || leafMap.isEmpty()) { + redis.del(groupKey); + } else { + String jsonData = gson.toJson(leafMap); + redis.set(groupKey, jsonData); + } + }); + + return true; + } + + + + + //根据VectorData的leaf属性列表获取向量数据列表,redis中的key是VectorData的group属性入参是List (class) + + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/VectorDtoTruncateService.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/VectorDtoTruncateService.java new file mode 100644 index 000000000..2e570adf1 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/impl/VectorDtoTruncateService.java @@ -0,0 +1,102 @@ +package run.mone.knowledge.service.impl; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import run.mone.knowledge.api.dto.*; +import run.mone.knowledge.api.enums.KnowledgeTypeEnum; +import run.mone.knowledge.service.EmbeddingService; +import run.mone.knowledge.service.dao.entity.VKnowledgeVectorDetailPo; +import run.mone.knowledge.service.dao.entity.VKnowledgeVectorMetaPo; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * @author wmin + * @date 2024/2/19 + */ +@Service +@Slf4j +public class VectorDtoTruncateService { + + public static Gson gson = new Gson(); + @Autowired + private EmbeddingService embeddingService; + + + /** + * 将qry入参转换为解析出leafTag和groupTag的fullDto + */ + public TagsFullInfo getSimilarKnowledgeVectorFullQry(TagsInfo qry, KnowledgeTypeEnum typeEnum) { + List tags = Arrays.asList(qry.getTag1(), qry.getTag2(), qry.getTag3(), qry.getTag4(), qry.getTag5(), qry.getTag6(), qry.getTag7()); + TagsFullInfo fullQry = new TagsFullInfo(); + fullQry.setTags(tags); + fullQry.setLeafTag(tags.get(typeEnum.getLeafTagIndex())); + fullQry.setGroupTag(tags.get(typeEnum.getGroupTagIndex())); + return fullQry; + } + + /** + * 将detail入参转换为解析出leafTag和groupTag的fullDto + */ + public KnowledgeVectorDetailFullDto getFullDto(KnowledgeVectorDetailDto detailDto, KnowledgeTypeEnum typeEnum) { + List tags = Arrays.asList(detailDto.getTag1(), detailDto.getTag2(), detailDto.getTag3(), detailDto.getTag4(), detailDto.getTag5(), detailDto.getTag6(), detailDto.getTag7()); + KnowledgeVectorDetailFullDto fullDto = new KnowledgeVectorDetailFullDto(); + fullDto.setType(typeEnum.getTypeName()); + fullDto.setDetailDto(detailDto); + fullDto.setFullTags(tags); + fullDto.setLeafTag(tags.get(typeEnum.getLeafTagIndex())); + fullDto.setGroupTag(tags.get(typeEnum.getGroupTagIndex())); + fullDto.setGroupTagIndex(typeEnum.getGroupTagIndex()); + fullDto.setLeafTagIndex(typeEnum.getLeafTagIndex()); + return fullDto; + } + + + /** + * 将VectorMeta dto转换为数据库PO + */ + public VKnowledgeVectorMetaPo convertVectorMetaDtoToPo(KnowledgeVectorDetailFullDto fullDto) { + KnowledgeVectorDetailDto detailDto = fullDto.getDetailDto(); + VKnowledgeVectorMetaPo vectorMeta = new VKnowledgeVectorMetaPo(); + vectorMeta.setType(fullDto.getType()); + vectorMeta.setTag1(detailDto.getTag1()); + int sum = fullDto.getGroupTagIndex() + 1; + int count = 0; + if (StringUtils.isNotBlank(detailDto.getTag2()) && ++count < sum) vectorMeta.setTag2(detailDto.getTag2()); + if (StringUtils.isNotBlank(detailDto.getTag3()) && ++count < sum) vectorMeta.setTag3(detailDto.getTag3()); + if (StringUtils.isNotBlank(detailDto.getTag4()) && ++count < sum) vectorMeta.setTag4(detailDto.getTag4()); + if (StringUtils.isNotBlank(detailDto.getTag5()) && ++count < sum) vectorMeta.setTag5(detailDto.getTag5()); + if (StringUtils.isNotBlank(detailDto.getTag6()) && ++count < sum) vectorMeta.setTag6(detailDto.getTag6()); + vectorMeta.setGroupTag(fullDto.getGroupTag()); + return vectorMeta; + } + + /** + * 将VectorDetail dto转换为数据库PO + */ + public VKnowledgeVectorDetailPo convertVectorDetailDtoToPo(KnowledgeVectorDetailFullDto fullDto) { + KnowledgeVectorDetailDto detailDto = fullDto.getDetailDto(); + VKnowledgeVectorDetailPo vectorMeta = new VKnowledgeVectorDetailPo(); + vectorMeta.setContent(detailDto.getContent()); + vectorMeta.setGmtCreate(new Date()); + vectorMeta.setLeafTag(fullDto.getLeafTag()); + vectorMeta.setType(fullDto.getType()); + if (detailDto.getVector() != null) { + vectorMeta.setVector(gson.toJson(detailDto.getVector())); + } + //todo 异步 + if (StringUtils.isNotBlank(detailDto.getContent())) { + String inputEmbedding = embeddingService.getEmbeddingStr(detailDto.getContent()); + vectorMeta.setVector(inputEmbedding); + detailDto.setVector(gson.fromJson(inputEmbedding, new TypeToken() { + }.getType())); + } + return vectorMeta; + } +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/DemoDepRpc.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/DemoDepRpc.java new file mode 100644 index 000000000..8e02f3086 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/DemoDepRpc.java @@ -0,0 +1,20 @@ +package run.mone.knowledge.service.rpc; + +import run.mone.knowledge.service.rpc.dto.DemoDepReqDto; +import run.mone.knowledge.service.rpc.dto.DemoDepResDto; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class DemoDepRpc { + + public DemoDepResDto remoteReq(DemoDepReqDto reqDto) { + log.info("DemoDepRpc.remoteReq 请求{}", reqDto); + //远程接口请求和响应要转换dto + DemoDepResDto resDto = DemoDepResDto.build(); + log.info("DemoDepRpc.remoteReq 响应{}", resDto); + return resDto; + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/dto/DemoDepReqDto.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/dto/DemoDepReqDto.java new file mode 100644 index 000000000..655952517 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/dto/DemoDepReqDto.java @@ -0,0 +1,19 @@ +package run.mone.knowledge.service.rpc.dto; + +import run.mone.knowledge.api.dto.DemoReqDto; +import lombok.Data; +import lombok.ToString; + +@ToString +@Data +public class DemoDepReqDto { + + private Long id; + + public static DemoDepReqDto build(DemoReqDto reqDto) { + DemoDepReqDto demoDepReqDto = new DemoDepReqDto(); + demoDepReqDto.id = reqDto.getId(); + return demoDepReqDto; + } + +} diff --git a/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/dto/DemoDepResDto.java b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/dto/DemoDepResDto.java new file mode 100644 index 000000000..2c7824d61 --- /dev/null +++ b/m78-all/private-knowledge/private-knowledge-service/src/main/java/run/mone/knowledge/service/rpc/dto/DemoDepResDto.java @@ -0,0 +1,17 @@ +package run.mone.knowledge.service.rpc.dto; + +import lombok.Data; +import lombok.ToString; + +@ToString +@Data +public class DemoDepResDto { + + private String test1; + + public static DemoDepResDto build() { + DemoDepResDto resDto = new DemoDepResDto(); + resDto.test1 = "test1"; + return resDto; + } +} diff --git a/m78-all/z-desensitization/.gitignore b/m78-all/z-desensitization/.gitignore new file mode 100644 index 000000000..6f91ee198 --- /dev/null +++ b/m78-all/z-desensitization/.gitignore @@ -0,0 +1,24 @@ +*.bak +build_info.properties +.classpath +dependency-reduced-pom.xml +*.diff +.DS_Store + +# IDEA +.idea/ +*.iml +logs/ +log/ + +# eclipse (Scala IDE) +.project +.settings/ +.tags* +target/ +test-output/ +nohup* +*.log +*.swp +*.pyc +.sbtserver* \ No newline at end of file diff --git a/m78-all/z-desensitization/README.md b/m78-all/z-desensitization/README.md new file mode 100644 index 000000000..34cd855e9 --- /dev/null +++ b/m78-all/z-desensitization/README.md @@ -0,0 +1,5 @@ +# 概述 ++ 用来测试mesh方案的代码 ++ springboot 2.2 的版本 ++ 测试 ++ curl http://127.0.0.1:8085/md5 \ No newline at end of file diff --git a/m78-all/z-desensitization/pom.xml b/m78-all/z-desensitization/pom.xml new file mode 100644 index 000000000..9f63998ac --- /dev/null +++ b/m78-all/z-desensitization/pom.xml @@ -0,0 +1,166 @@ + + + + 4.0.0 + run.mone.z + z-desensitization + 1.0-SNAPSHOT + pom + + + z-desensitization-api + z-desensitization-domain + z-desensitization-infrastructure + z-desensitization-app + z-desensitization-server + + + + + + org.springframework.boot + spring-boot-starter-web + 2.7.7 + + + org.springframework.boot + spring-boot-starter-logging + 2.7.7 + + + org.springframework.boot + spring-boot-starter-test + 2.7.7 + + + org.yaml + snakeyaml + + + + + com.fasterxml.jackson.core + jackson-core + 2.13.4 + + + io.netty + netty-all + 4.1.52.Final + + + org.codehaus.mojo + animal-sniffer-annotations + 1.19 + + + com.google.code.gson + gson + 2.8.6 + + + org.slf4j + slf4j-api + 1.7.36 + compile + + + cglib + cglib-nodep + 3.3.0 + + + commons-codec + commons-codec + 1.11 + + + org.apache.commons + commons-lang3 + 3.7 + + + com.google.errorprone + error_prone_annotations + 2.4.0 + runtime + + + com.google.guava + guava + 31.0.1-jre + compile + + + com.caucho + hessian + 4.0.65 + + + org.apache.httpcomponents + httpclient + 4.5.5 + + + org.apache.httpcomponents + httpcore + 4.4.9 + + + com.fasterxml.jackson.core + jackson-databind + 2.13.4 + compile + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 1.8 + 1.8 + true + true + UTF-8 + + + ${project.basedir}/src/main/java + + + + + + run.mone + jarcheck-maven-plugin + 1.4-SNAPSHOT + + + package + + jarCheck + + + + + + + + + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + diff --git a/m78-all/z-desensitization/z-desensitization-api/pom.xml b/m78-all/z-desensitization/z-desensitization-api/pom.xml new file mode 100644 index 000000000..bd97d35b2 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-api/pom.xml @@ -0,0 +1,28 @@ + + + + + z-desensitization + run.mone.z + 1.0-SNAPSHOT + + 4.0.0 + + z-desensitization-api + + + + + + run.mone + infra-result + 1.4-SNAPSHOT + + + + + + + \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/bo/DesensitizeReq.java b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/bo/DesensitizeReq.java new file mode 100644 index 000000000..0463748f4 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/bo/DesensitizeReq.java @@ -0,0 +1,68 @@ +package run.mone.z.desensitization.api.bo; + +import java.io.Serializable; +import java.util.List; + +/** + * @author wmin + * @date 2023/11/14 + */ +public class DesensitizeReq implements Serializable { + private String text; + private List sensitiveWordConfigBo; + private Boolean aiDesensitizeFlag; + + private Boolean needExtract; + + private String langType; + + private String username; + + public String getLangType() { + return langType; + } + + public void setLangType(String langType) { + this.langType = langType; + } + + public Boolean getNeedExtract() { + return needExtract; + } + + public void setNeedExtract(Boolean needExtract) { + this.needExtract = needExtract; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public List getSensitiveWordConfigBo() { + return sensitiveWordConfigBo; + } + + public void setSensitiveWordConfigBo(List sensitiveWordConfigBo) { + this.sensitiveWordConfigBo = sensitiveWordConfigBo; + } + + public Boolean getAiDesensitizeFlag() { + return aiDesensitizeFlag; + } + + public void setAiDesensitizeFlag(Boolean aiDesensitizeFlag) { + this.aiDesensitizeFlag = aiDesensitizeFlag; + } +} diff --git a/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/bo/SensitiveWordConfigBo.java b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/bo/SensitiveWordConfigBo.java new file mode 100644 index 000000000..231cce020 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/bo/SensitiveWordConfigBo.java @@ -0,0 +1,51 @@ +package run.mone.z.desensitization.api.bo; + +import run.mone.z.desensitization.api.common.SensitiveWordTypeEnum; + +import java.io.Serializable; + +/** + * @author wmin + * @date 2023/11/14 + */ +public class SensitiveWordConfigBo implements Serializable { + /** + * @see SensitiveWordTypeEnum + */ + private Integer type; + private String content; + private Boolean isRegexMatch; + private Boolean isCaseSensitive; + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public Boolean getRegexMatch() { + return isRegexMatch; + } + + public void setRegexMatch(Boolean regexMatch) { + isRegexMatch = regexMatch; + } + + public Boolean getCaseSensitive() { + return isCaseSensitive; + } + + public void setCaseSensitive(Boolean caseSensitive) { + isCaseSensitive = caseSensitive; + } +} diff --git a/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/common/CodeTypeEnum.java b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/common/CodeTypeEnum.java new file mode 100644 index 000000000..b7d6e4e38 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/common/CodeTypeEnum.java @@ -0,0 +1,20 @@ +package run.mone.z.desensitization.api.common; + +/** + * @author wmin + * @date 2023/6/5 + */ +public enum CodeTypeEnum { + CLASS("class"), + METHOD("method"); + + private String type; + + public String getType() { + return type; + } + + CodeTypeEnum(String type) { + this.type = type; + } +} diff --git a/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/common/SensitiveWordTypeEnum.java b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/common/SensitiveWordTypeEnum.java new file mode 100644 index 000000000..9b80663e8 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/common/SensitiveWordTypeEnum.java @@ -0,0 +1,35 @@ +package run.mone.z.desensitization.api.common; + +public enum SensitiveWordTypeEnum { + All(0, "不限制"), + FiledKey(1, "属性名"), + FiledValue(2, "属性值"); + public final int code; + public final String description; + + SensitiveWordTypeEnum(int code, String description) { + this.code = code; + this.description = description; + } + + public int getCode() { + return code; + } + + public String getDescription() { + return description; + } + + public static boolean check(Integer type){ + if(type==null){ + return false; + } + SensitiveWordTypeEnum[] values = SensitiveWordTypeEnum.values(); + for (SensitiveWordTypeEnum envEnum : values) { + if(type==envEnum.getCode()){ + return true; + } + } + return false; + } +} diff --git a/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/service/CodeDesensitizeService.java b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/service/CodeDesensitizeService.java new file mode 100644 index 000000000..7f033d16e --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/service/CodeDesensitizeService.java @@ -0,0 +1,25 @@ +package run.mone.z.desensitization.api.service; + +import com.xiaomi.youpin.infra.rpc.Result; +import run.mone.z.desensitization.api.bo.DesensitizeReq; + +/** + * @author wmin + * @date 2023/6/5 + */ +public interface CodeDesensitizeService { + + /** + * @param codeSnippet 纯代码片段 + * @return + */ + Result codeDesensitize(String codeSnippet); + + /** + * @param text 包含代码片段的文本 + * @return + */ + Result textDesensitize(String text); + + Result textDesensitizeWithAi(DesensitizeReq req); +} diff --git a/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/service/DubboHealthService.java b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/service/DubboHealthService.java new file mode 100644 index 000000000..b3766d70f --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-api/src/main/java/run/mone/z/desensitization/api/service/DubboHealthService.java @@ -0,0 +1,10 @@ +package run.mone.z.desensitization.api.service; + + +import com.xiaomi.youpin.infra.rpc.Result; + +public interface DubboHealthService { + + Result health(); + +} \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-app/pom.xml b/m78-all/z-desensitization/z-desensitization-app/pom.xml new file mode 100644 index 000000000..2132d9c50 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/pom.xml @@ -0,0 +1,56 @@ + + + z-desensitization + run.mone.z + 1.0-SNAPSHOT + + 4.0.0 + z-desensitization-app + + + + + z-desensitization-api + run.mone.z + 1.0-SNAPSHOT + + + + z-desensitization-domain + run.mone.z + 1.0-SNAPSHOT + + + + org.antlr + antlr4-runtime + 4.7.1 + + + org.antlr + antlr4 + 4.7.1 + + + + com.github.javaparser + javaparser-core + 3.23.1 + + + com.sun + tools + 1.8 + system + ${java.home}/../lib/tools.jar + + + org.jetbrains + annotations + 24.1.0 + test + + + + diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/Field.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/Field.java new file mode 100644 index 000000000..2b85f018f --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/Field.java @@ -0,0 +1,22 @@ +package run.mone.antlr.golang; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2024/2/1 22:47 + */ +@Data +@Builder +public class Field implements Serializable { + + public String k; + + public String v; + + public String type; + +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoCode.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoCode.java new file mode 100644 index 000000000..8d205040c --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoCode.java @@ -0,0 +1,107 @@ +package run.mone.antlr.golang; + +import lombok.extern.slf4j.Slf4j; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.ParseTreeWalker; +import org.antlr.v4.runtime.tree.TerminalNode; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2024/1/29 16:56 + */ +@Slf4j +public class GoCode { + + + public static ParseResult parse(String code) { + GoLexer lexer = new GoLexer(new ANTLRInputStream(code)); + CommonTokenStream tokens = new CommonTokenStream(lexer); + GoParser parser = new GoParser(tokens); + + parser.addErrorListener(new BaseErrorListener() { + @Override + public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { + log.error("line:" + line + " msg:" + msg); + } + }); + + ParseTree tree = parser.sourceFile(); + ParseTreeWalker walker = new ParseTreeWalker(); + + List list = new ArrayList<>(); + + Map> map = new HashMap<>(); + + GoParserListener listener = new GoParserBaseListener() { + + @Override + public void enterCompositeLit(GoParser.CompositeLitContext ctx) { + // 遍历所有的键值初始化 + for (GoParser.KeyedElementContext keyedElement : ctx.literalValue().elementList().keyedElement()) { + String key = keyedElement.key().getText(); + System.out.println("key:" + key + " value:" + keyedElement.element().getText()); + list.add(Field.builder().k(key).v(keyedElement.element().getText()).type("CompositeLit").build()); + } + } + + @Override + public void enterVarSpec(GoParser.VarSpecContext ctx) { + // 获取变量名 + String varName = ctx.identifierList().getText(); + // 获取变量的初始化值 + String varValue = ctx.expressionList().getText(); + list.add(Field.builder().k(varName).v(varValue).type("VarSpec").build()); + } + + + @Override + public void enterArguments(GoParser.ArgumentsContext ctx) { + int count = ctx.getChildCount(); + if (count == 3) { + list.add(Field.builder().k(ctx.getParent().getChild(0).getText()).v(ctx.getChild(1).getText()).type("method").build()); + } + } + + @Override + public void enterFunctionDecl(GoParser.FunctionDeclContext ctx) { + //解析方法名和参数名 + List pList = ctx.signature().parameters().parameterDecl(); + List l2 = pList.stream().map(it -> { + return it.identifierList().IDENTIFIER().stream().map(it2 -> it2.getText()).collect(Collectors.joining(",")); + }).collect(Collectors.toList()); + + map.put(ctx.getChild(1).getText(),l2); + } + + + @Override + public void enterMethodDecl(GoParser.MethodDeclContext ctx) { + // 检查是否是结构体的方法 + if (ctx.receiver() != null) { + //解析方法名和参数名 + List pList = ctx.signature().parameters().parameterDecl(); + List l2 = pList.stream().map(it -> { + return it.identifierList().IDENTIFIER().stream().map(it2 -> it2.getText()).collect(Collectors.joining(",")); + }).collect(Collectors.toList()); + //0 func 1 receiver 2 methodName + map.put(ctx.getChild(2).getText(),l2); + } + + } + }; + walker.walk(listener, tree); + return ParseResult.builder().fieldList(list).methodMap(map).build(); + } + + + +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.interp b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.interp new file mode 100644 index 000000000..3a9e86363 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.interp @@ -0,0 +1,301 @@ +token literal names: +null +'break' +'default' +'func' +'interface' +'select' +'case' +'defer' +'go' +'map' +'struct' +'chan' +'else' +'goto' +'package' +'switch' +'const' +'fallthrough' +'if' +'range' +'type' +'continue' +'for' +'import' +'return' +'var' +'nil' +null +'(' +')' +'{' +'}' +'[' +']' +'=' +',' +';' +':' +'.' +'++' +'--' +':=' +'...' +'||' +'&&' +'==' +'!=' +'<' +'<=' +'>' +'>=' +'|' +'/' +'%' +'<<' +'>>' +'&^' +'~' +'!' +'+' +'-' +'^' +'*' +'&' +'<-' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +BREAK +DEFAULT +FUNC +INTERFACE +SELECT +CASE +DEFER +GO +MAP +STRUCT +CHAN +ELSE +GOTO +PACKAGE +SWITCH +CONST +FALLTHROUGH +IF +RANGE +TYPE +CONTINUE +FOR +IMPORT +RETURN +VAR +NIL_LIT +IDENTIFIER +L_PAREN +R_PAREN +L_CURLY +R_CURLY +L_BRACKET +R_BRACKET +ASSIGN +COMMA +SEMI +COLON +DOT +PLUS_PLUS +MINUS_MINUS +DECLARE_ASSIGN +ELLIPSIS +LOGICAL_OR +LOGICAL_AND +EQUALS +NOT_EQUALS +LESS +LESS_OR_EQUALS +GREATER +GREATER_OR_EQUALS +OR +DIV +MOD +LSHIFT +RSHIFT +BIT_CLEAR +UNDERLYING +EXCLAMATION +PLUS +MINUS +CARET +STAR +AMPERSAND +RECEIVE +DECIMAL_LIT +BINARY_LIT +OCTAL_LIT +HEX_LIT +FLOAT_LIT +DECIMAL_FLOAT_LIT +HEX_FLOAT_LIT +IMAGINARY_LIT +RUNE_LIT +BYTE_VALUE +OCTAL_BYTE_VALUE +HEX_BYTE_VALUE +LITTLE_U_VALUE +BIG_U_VALUE +RAW_STRING_LIT +INTERPRETED_STRING_LIT +WS +COMMENT +TERMINATOR +LINE_COMMENT +NEWLINE +WS_NLSEMI +COMMENT_NLSEMI +LINE_COMMENT_NLSEMI +EOS +OTHER + +rule names: +BREAK +DEFAULT +FUNC +INTERFACE +SELECT +CASE +DEFER +GO +MAP +STRUCT +CHAN +ELSE +GOTO +PACKAGE +SWITCH +CONST +FALLTHROUGH +IF +RANGE +TYPE +CONTINUE +FOR +IMPORT +RETURN +VAR +NIL_LIT +IDENTIFIER +L_PAREN +R_PAREN +L_CURLY +R_CURLY +L_BRACKET +R_BRACKET +ASSIGN +COMMA +SEMI +COLON +DOT +PLUS_PLUS +MINUS_MINUS +DECLARE_ASSIGN +ELLIPSIS +LOGICAL_OR +LOGICAL_AND +EQUALS +NOT_EQUALS +LESS +LESS_OR_EQUALS +GREATER +GREATER_OR_EQUALS +OR +DIV +MOD +LSHIFT +RSHIFT +BIT_CLEAR +UNDERLYING +EXCLAMATION +PLUS +MINUS +CARET +STAR +AMPERSAND +RECEIVE +DECIMAL_LIT +BINARY_LIT +OCTAL_LIT +HEX_LIT +FLOAT_LIT +DECIMAL_FLOAT_LIT +HEX_FLOAT_LIT +HEX_MANTISSA +HEX_EXPONENT +IMAGINARY_LIT +RUNE +RUNE_LIT +BYTE_VALUE +OCTAL_BYTE_VALUE +HEX_BYTE_VALUE +LITTLE_U_VALUE +BIG_U_VALUE +RAW_STRING_LIT +INTERPRETED_STRING_LIT +WS +COMMENT +TERMINATOR +LINE_COMMENT +NEWLINE +UNICODE_VALUE +ESCAPED_VALUE +DECIMALS +OCTAL_DIGIT +HEX_DIGIT +BIN_DIGIT +EXPONENT +LETTER +UNICODE_DIGIT +UNICODE_LETTER +WS_NLSEMI +COMMENT_NLSEMI +LINE_COMMENT_NLSEMI +EOS +OTHER + +channel names: +DEFAULT_TOKEN_CHANNEL +HIDDEN + +mode names: +DEFAULT_MODE +NLSEMI + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 92, 863, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 7, 28, 382, 10, 28, 12, 28, 14, 28, 385, 11, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 36, 3, 36, 3, 37, 3, 37, 3, 38, 3, 38, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 53, 3, 53, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 59, 3, 59, 3, 60, 3, 60, 3, 61, 3, 61, 3, 62, 3, 62, 3, 63, 3, 63, 3, 64, 3, 64, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 66, 5, 66, 491, 10, 66, 3, 66, 7, 66, 494, 10, 66, 12, 66, 14, 66, 497, 11, 66, 5, 66, 499, 10, 66, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 5, 67, 506, 10, 67, 3, 67, 6, 67, 509, 10, 67, 13, 67, 14, 67, 510, 3, 67, 3, 67, 3, 68, 3, 68, 5, 68, 517, 10, 68, 3, 68, 5, 68, 520, 10, 68, 3, 68, 6, 68, 523, 10, 68, 13, 68, 14, 68, 524, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 5, 69, 532, 10, 69, 3, 69, 6, 69, 535, 10, 69, 13, 69, 14, 69, 536, 3, 69, 3, 69, 3, 70, 3, 70, 5, 70, 543, 10, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 5, 71, 550, 10, 71, 3, 71, 5, 71, 553, 10, 71, 3, 71, 5, 71, 556, 10, 71, 3, 71, 3, 71, 3, 71, 5, 71, 561, 10, 71, 5, 71, 563, 10, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 3, 73, 5, 73, 571, 10, 73, 3, 73, 6, 73, 574, 10, 73, 13, 73, 14, 73, 575, 3, 73, 3, 73, 5, 73, 580, 10, 73, 3, 73, 7, 73, 583, 10, 73, 12, 73, 14, 73, 586, 11, 73, 5, 73, 588, 10, 73, 3, 73, 3, 73, 3, 73, 5, 73, 593, 10, 73, 3, 73, 7, 73, 596, 10, 73, 12, 73, 14, 73, 599, 11, 73, 5, 73, 601, 10, 73, 3, 74, 3, 74, 5, 74, 605, 10, 74, 3, 74, 3, 74, 3, 75, 3, 75, 3, 75, 3, 75, 3, 75, 5, 75, 614, 10, 75, 3, 75, 3, 75, 3, 75, 3, 75, 3, 76, 3, 76, 3, 76, 5, 76, 623, 10, 76, 3, 76, 3, 76, 3, 77, 3, 77, 3, 77, 3, 77, 3, 78, 3, 78, 5, 78, 633, 10, 78, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 81, 3, 81, 3, 81, 3, 81, 3, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 3, 82, 3, 82, 3, 82, 3, 82, 3, 82, 3, 82, 3, 82, 3, 82, 3, 83, 3, 83, 7, 83, 665, 10, 83, 12, 83, 14, 83, 668, 11, 83, 3, 83, 3, 83, 3, 83, 3, 83, 3, 84, 3, 84, 3, 84, 7, 84, 677, 10, 84, 12, 84, 14, 84, 680, 11, 84, 3, 84, 3, 84, 3, 84, 3, 84, 3, 85, 6, 85, 687, 10, 85, 13, 85, 14, 85, 688, 3, 85, 3, 85, 3, 86, 3, 86, 3, 86, 3, 86, 7, 86, 697, 10, 86, 12, 86, 14, 86, 700, 11, 86, 3, 86, 3, 86, 3, 86, 3, 86, 3, 86, 3, 87, 6, 87, 708, 10, 87, 13, 87, 14, 87, 709, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 88, 7, 88, 718, 10, 88, 12, 88, 14, 88, 721, 11, 88, 3, 88, 3, 88, 3, 89, 5, 89, 726, 10, 89, 3, 89, 3, 89, 6, 89, 730, 10, 89, 13, 89, 14, 89, 731, 3, 89, 6, 89, 735, 10, 89, 13, 89, 14, 89, 736, 5, 89, 739, 10, 89, 3, 90, 3, 90, 3, 90, 3, 90, 5, 90, 745, 10, 90, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 3, 91, 5, 91, 773, 10, 91, 3, 92, 3, 92, 5, 92, 777, 10, 92, 3, 92, 7, 92, 780, 10, 92, 12, 92, 14, 92, 783, 11, 92, 3, 93, 3, 93, 3, 94, 3, 94, 3, 95, 3, 95, 3, 96, 3, 96, 5, 96, 793, 10, 96, 3, 96, 3, 96, 3, 97, 3, 97, 5, 97, 799, 10, 97, 3, 98, 3, 98, 3, 99, 3, 99, 3, 100, 6, 100, 806, 10, 100, 13, 100, 14, 100, 807, 3, 100, 3, 100, 3, 101, 3, 101, 3, 101, 3, 101, 7, 101, 816, 10, 101, 12, 101, 14, 101, 819, 11, 101, 3, 101, 3, 101, 3, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 102, 7, 102, 830, 10, 102, 12, 102, 14, 102, 833, 11, 102, 3, 102, 3, 102, 3, 103, 6, 103, 838, 10, 103, 13, 103, 14, 103, 839, 3, 103, 3, 103, 3, 103, 3, 103, 3, 103, 7, 103, 847, 10, 103, 12, 103, 14, 103, 850, 11, 103, 3, 103, 3, 103, 3, 103, 5, 103, 855, 10, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 104, 5, 698, 817, 848, 2, 105, 4, 3, 6, 4, 8, 5, 10, 6, 12, 7, 14, 8, 16, 9, 18, 10, 20, 11, 22, 12, 24, 13, 26, 14, 28, 15, 30, 16, 32, 17, 34, 18, 36, 19, 38, 20, 40, 21, 42, 22, 44, 23, 46, 24, 48, 25, 50, 26, 52, 27, 54, 28, 56, 29, 58, 30, 60, 31, 62, 32, 64, 33, 66, 34, 68, 35, 70, 36, 72, 37, 74, 38, 76, 39, 78, 40, 80, 41, 82, 42, 84, 43, 86, 44, 88, 45, 90, 46, 92, 47, 94, 48, 96, 49, 98, 50, 100, 51, 102, 52, 104, 53, 106, 54, 108, 55, 110, 56, 112, 57, 114, 58, 116, 59, 118, 60, 120, 61, 122, 62, 124, 63, 126, 64, 128, 65, 130, 66, 132, 67, 134, 68, 136, 69, 138, 70, 140, 71, 142, 72, 144, 73, 146, 2, 148, 2, 150, 74, 152, 2, 154, 75, 156, 76, 158, 77, 160, 78, 162, 79, 164, 80, 166, 81, 168, 82, 170, 83, 172, 84, 174, 85, 176, 86, 178, 87, 180, 2, 182, 2, 184, 2, 186, 2, 188, 2, 190, 2, 192, 2, 194, 2, 196, 2, 198, 2, 200, 88, 202, 89, 204, 90, 206, 91, 208, 92, 4, 2, 3, 19, 3, 2, 51, 59, 3, 2, 50, 59, 4, 2, 68, 68, 100, 100, 4, 2, 81, 81, 113, 113, 4, 2, 90, 90, 122, 122, 4, 2, 82, 82, 114, 114, 4, 2, 45, 45, 47, 47, 3, 2, 98, 98, 4, 2, 36, 36, 94, 94, 4, 2, 11, 11, 34, 34, 4, 2, 12, 12, 15, 15, 5, 2, 12, 12, 15, 15, 41, 41, 11, 2, 36, 36, 41, 41, 94, 94, 99, 100, 104, 104, 112, 112, 116, 116, 118, 118, 120, 120, 3, 2, 50, 57, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 51, 4, 2, 71, 71, 103, 103, 4, 56, 2, 50, 2, 59, 2, 1634, 2, 1643, 2, 1778, 2, 1787, 2, 1986, 2, 1995, 2, 2408, 2, 2417, 2, 2536, 2, 2545, 2, 2664, 2, 2673, 2, 2792, 2, 2801, 2, 2920, 2, 2929, 2, 3048, 2, 3057, 2, 3176, 2, 3185, 2, 3304, 2, 3313, 2, 3432, 2, 3441, 2, 3560, 2, 3569, 2, 3666, 2, 3675, 2, 3794, 2, 3803, 2, 3874, 2, 3883, 2, 4162, 2, 4171, 2, 4242, 2, 4251, 2, 6114, 2, 6123, 2, 6162, 2, 6171, 2, 6472, 2, 6481, 2, 6610, 2, 6619, 2, 6786, 2, 6795, 2, 6802, 2, 6811, 2, 6994, 2, 7003, 2, 7090, 2, 7099, 2, 7234, 2, 7243, 2, 7250, 2, 7259, 2, 42530, 2, 42539, 2, 43218, 2, 43227, 2, 43266, 2, 43275, 2, 43474, 2, 43483, 2, 43506, 2, 43515, 2, 43602, 2, 43611, 2, 44018, 2, 44027, 2, 65298, 2, 65307, 2, 1186, 3, 1195, 3, 4200, 3, 4209, 3, 4338, 3, 4347, 3, 4408, 3, 4417, 3, 4562, 3, 4571, 3, 4850, 3, 4859, 3, 5202, 3, 5211, 3, 5330, 3, 5339, 3, 5714, 3, 5723, 3, 5826, 3, 5835, 3, 5938, 3, 5947, 3, 6370, 3, 6379, 3, 7250, 3, 7259, 3, 27234, 3, 27243, 3, 27474, 3, 27483, 3, 55248, 3, 55297, 3, 59730, 3, 59739, 3, 573, 2, 67, 2, 92, 2, 99, 2, 124, 2, 172, 2, 172, 2, 183, 2, 183, 2, 188, 2, 188, 2, 194, 2, 216, 2, 218, 2, 248, 2, 250, 2, 707, 2, 712, 2, 723, 2, 738, 2, 742, 2, 750, 2, 750, 2, 752, 2, 752, 2, 882, 2, 886, 2, 888, 2, 889, 2, 892, 2, 895, 2, 897, 2, 897, 2, 904, 2, 904, 2, 906, 2, 908, 2, 910, 2, 910, 2, 912, 2, 931, 2, 933, 2, 1015, 2, 1017, 2, 1155, 2, 1164, 2, 1329, 2, 1331, 2, 1368, 2, 1371, 2, 1371, 2, 1379, 2, 1417, 2, 1490, 2, 1516, 2, 1522, 2, 1524, 2, 1570, 2, 1612, 2, 1648, 2, 1649, 2, 1651, 2, 1749, 2, 1751, 2, 1751, 2, 1767, 2, 1768, 2, 1776, 2, 1777, 2, 1788, 2, 1790, 2, 1793, 2, 1793, 2, 1810, 2, 1810, 2, 1812, 2, 1841, 2, 1871, 2, 1959, 2, 1971, 2, 1971, 2, 1996, 2, 2028, 2, 2038, 2, 2039, 2, 2044, 2, 2044, 2, 2050, 2, 2071, 2, 2076, 2, 2076, 2, 2086, 2, 2086, 2, 2090, 2, 2090, 2, 2114, 2, 2138, 2, 2210, 2, 2230, 2, 2232, 2, 2239, 2, 2310, 2, 2363, 2, 2367, 2, 2367, 2, 2386, 2, 2386, 2, 2394, 2, 2403, 2, 2419, 2, 2434, 2, 2439, 2, 2446, 2, 2449, 2, 2450, 2, 2453, 2, 2474, 2, 2476, 2, 2482, 2, 2484, 2, 2484, 2, 2488, 2, 2491, 2, 2495, 2, 2495, 2, 2512, 2, 2512, 2, 2526, 2, 2527, 2, 2529, 2, 2531, 2, 2546, 2, 2547, 2, 2567, 2, 2572, 2, 2577, 2, 2578, 2, 2581, 2, 2602, 2, 2604, 2, 2610, 2, 2612, 2, 2613, 2, 2615, 2, 2616, 2, 2618, 2, 2619, 2, 2651, 2, 2654, 2, 2656, 2, 2656, 2, 2676, 2, 2678, 2, 2695, 2, 2703, 2, 2705, 2, 2707, 2, 2709, 2, 2730, 2, 2732, 2, 2738, 2, 2740, 2, 2741, 2, 2743, 2, 2747, 2, 2751, 2, 2751, 2, 2770, 2, 2770, 2, 2786, 2, 2787, 2, 2811, 2, 2811, 2, 2823, 2, 2830, 2, 2833, 2, 2834, 2, 2837, 2, 2858, 2, 2860, 2, 2866, 2, 2868, 2, 2869, 2, 2871, 2, 2875, 2, 2879, 2, 2879, 2, 2910, 2, 2911, 2, 2913, 2, 2915, 2, 2931, 2, 2931, 2, 2949, 2, 2949, 2, 2951, 2, 2956, 2, 2960, 2, 2962, 2, 2964, 2, 2967, 2, 2971, 2, 2972, 2, 2974, 2, 2974, 2, 2976, 2, 2977, 2, 2981, 2, 2982, 2, 2986, 2, 2988, 2, 2992, 2, 3003, 2, 3026, 2, 3026, 2, 3079, 2, 3086, 2, 3088, 2, 3090, 2, 3092, 2, 3114, 2, 3116, 2, 3131, 2, 3135, 2, 3135, 2, 3162, 2, 3164, 2, 3170, 2, 3171, 2, 3202, 2, 3202, 2, 3207, 2, 3214, 2, 3216, 2, 3218, 2, 3220, 2, 3242, 2, 3244, 2, 3253, 2, 3255, 2, 3259, 2, 3263, 2, 3263, 2, 3296, 2, 3296, 2, 3298, 2, 3299, 2, 3315, 2, 3316, 2, 3335, 2, 3342, 2, 3344, 2, 3346, 2, 3348, 2, 3388, 2, 3391, 2, 3391, 2, 3408, 2, 3408, 2, 3414, 2, 3416, 2, 3425, 2, 3427, 2, 3452, 2, 3457, 2, 3463, 2, 3480, 2, 3484, 2, 3507, 2, 3509, 2, 3517, 2, 3519, 2, 3519, 2, 3522, 2, 3528, 2, 3587, 2, 3634, 2, 3636, 2, 3637, 2, 3650, 2, 3656, 2, 3715, 2, 3716, 2, 3718, 2, 3718, 2, 3721, 2, 3722, 2, 3724, 2, 3724, 2, 3727, 2, 3727, 2, 3734, 2, 3737, 2, 3739, 2, 3745, 2, 3747, 2, 3749, 2, 3751, 2, 3751, 2, 3753, 2, 3753, 2, 3756, 2, 3757, 2, 3759, 2, 3762, 2, 3764, 2, 3765, 2, 3775, 2, 3775, 2, 3778, 2, 3782, 2, 3784, 2, 3784, 2, 3806, 2, 3809, 2, 3842, 2, 3842, 2, 3906, 2, 3913, 2, 3915, 2, 3950, 2, 3978, 2, 3982, 2, 4098, 2, 4140, 2, 4161, 2, 4161, 2, 4178, 2, 4183, 2, 4188, 2, 4191, 2, 4195, 2, 4195, 2, 4199, 2, 4200, 2, 4208, 2, 4210, 2, 4215, 2, 4227, 2, 4240, 2, 4240, 2, 4258, 2, 4295, 2, 4297, 2, 4297, 2, 4303, 2, 4303, 2, 4306, 2, 4348, 2, 4350, 2, 4682, 2, 4684, 2, 4687, 2, 4690, 2, 4696, 2, 4698, 2, 4698, 2, 4700, 2, 4703, 2, 4706, 2, 4746, 2, 4748, 2, 4751, 2, 4754, 2, 4786, 2, 4788, 2, 4791, 2, 4794, 2, 4800, 2, 4802, 2, 4802, 2, 4804, 2, 4807, 2, 4810, 2, 4824, 2, 4826, 2, 4882, 2, 4884, 2, 4887, 2, 4890, 2, 4956, 2, 4994, 2, 5009, 2, 5026, 2, 5111, 2, 5114, 2, 5119, 2, 5123, 2, 5742, 2, 5745, 2, 5761, 2, 5763, 2, 5788, 2, 5794, 2, 5868, 2, 5875, 2, 5882, 2, 5890, 2, 5902, 2, 5904, 2, 5907, 2, 5922, 2, 5939, 2, 5954, 2, 5971, 2, 5986, 2, 5998, 2, 6000, 2, 6002, 2, 6018, 2, 6069, 2, 6105, 2, 6105, 2, 6110, 2, 6110, 2, 6178, 2, 6265, 2, 6274, 2, 6278, 2, 6281, 2, 6314, 2, 6316, 2, 6316, 2, 6322, 2, 6391, 2, 6402, 2, 6432, 2, 6482, 2, 6511, 2, 6514, 2, 6518, 2, 6530, 2, 6573, 2, 6578, 2, 6603, 2, 6658, 2, 6680, 2, 6690, 2, 6742, 2, 6825, 2, 6825, 2, 6919, 2, 6965, 2, 6983, 2, 6989, 2, 7045, 2, 7074, 2, 7088, 2, 7089, 2, 7100, 2, 7143, 2, 7170, 2, 7205, 2, 7247, 2, 7249, 2, 7260, 2, 7295, 2, 7298, 2, 7306, 2, 7403, 2, 7406, 2, 7408, 2, 7411, 2, 7415, 2, 7416, 2, 7426, 2, 7617, 2, 7682, 2, 7959, 2, 7962, 2, 7967, 2, 7970, 2, 8007, 2, 8010, 2, 8015, 2, 8018, 2, 8025, 2, 8027, 2, 8027, 2, 8029, 2, 8029, 2, 8031, 2, 8031, 2, 8033, 2, 8063, 2, 8066, 2, 8118, 2, 8120, 2, 8126, 2, 8128, 2, 8128, 2, 8132, 2, 8134, 2, 8136, 2, 8142, 2, 8146, 2, 8149, 2, 8152, 2, 8157, 2, 8162, 2, 8174, 2, 8180, 2, 8182, 2, 8184, 2, 8190, 2, 8307, 2, 8307, 2, 8321, 2, 8321, 2, 8338, 2, 8350, 2, 8452, 2, 8452, 2, 8457, 2, 8457, 2, 8460, 2, 8469, 2, 8471, 2, 8471, 2, 8475, 2, 8479, 2, 8486, 2, 8486, 2, 8488, 2, 8488, 2, 8490, 2, 8490, 2, 8492, 2, 8495, 2, 8497, 2, 8507, 2, 8510, 2, 8513, 2, 8519, 2, 8523, 2, 8528, 2, 8528, 2, 8581, 2, 8582, 2, 11266, 2, 11312, 2, 11314, 2, 11360, 2, 11362, 2, 11494, 2, 11501, 2, 11504, 2, 11508, 2, 11509, 2, 11522, 2, 11559, 2, 11561, 2, 11561, 2, 11567, 2, 11567, 2, 11570, 2, 11625, 2, 11633, 2, 11633, 2, 11650, 2, 11672, 2, 11682, 2, 11688, 2, 11690, 2, 11696, 2, 11698, 2, 11704, 2, 11706, 2, 11712, 2, 11714, 2, 11720, 2, 11722, 2, 11728, 2, 11730, 2, 11736, 2, 11738, 2, 11744, 2, 11825, 2, 11825, 2, 12295, 2, 12296, 2, 12339, 2, 12343, 2, 12349, 2, 12350, 2, 12355, 2, 12440, 2, 12447, 2, 12449, 2, 12451, 2, 12540, 2, 12542, 2, 12545, 2, 12551, 2, 12591, 2, 12595, 2, 12688, 2, 12706, 2, 12732, 2, 12786, 2, 12801, 2, 13314, 2, 19895, 2, 19970, 2, 40919, 2, 40962, 2, 42126, 2, 42194, 2, 42239, 2, 42242, 2, 42510, 2, 42514, 2, 42529, 2, 42540, 2, 42541, 2, 42562, 2, 42608, 2, 42625, 2, 42655, 2, 42658, 2, 42727, 2, 42777, 2, 42785, 2, 42788, 2, 42890, 2, 42893, 2, 42928, 2, 42930, 2, 42937, 2, 43001, 2, 43011, 2, 43013, 2, 43015, 2, 43017, 2, 43020, 2, 43022, 2, 43044, 2, 43074, 2, 43125, 2, 43140, 2, 43189, 2, 43252, 2, 43257, 2, 43261, 2, 43261, 2, 43263, 2, 43263, 2, 43276, 2, 43303, 2, 43314, 2, 43336, 2, 43362, 2, 43390, 2, 43398, 2, 43444, 2, 43473, 2, 43473, 2, 43490, 2, 43494, 2, 43496, 2, 43505, 2, 43516, 2, 43520, 2, 43522, 2, 43562, 2, 43586, 2, 43588, 2, 43590, 2, 43597, 2, 43618, 2, 43640, 2, 43644, 2, 43644, 2, 43648, 2, 43697, 2, 43699, 2, 43699, 2, 43703, 2, 43704, 2, 43707, 2, 43711, 2, 43714, 2, 43714, 2, 43716, 2, 43716, 2, 43741, 2, 43743, 2, 43746, 2, 43756, 2, 43764, 2, 43766, 2, 43779, 2, 43784, 2, 43787, 2, 43792, 2, 43795, 2, 43800, 2, 43810, 2, 43816, 2, 43818, 2, 43824, 2, 43826, 2, 43868, 2, 43870, 2, 43879, 2, 43890, 2, 44004, 2, 44034, 2, 55205, 2, 55218, 2, 55240, 2, 55245, 2, 55293, 2, 63746, 2, 64111, 2, 64114, 2, 64219, 2, 64258, 2, 64264, 2, 64277, 2, 64281, 2, 64287, 2, 64287, 2, 64289, 2, 64298, 2, 64300, 2, 64312, 2, 64314, 2, 64318, 2, 64320, 2, 64320, 2, 64322, 2, 64323, 2, 64325, 2, 64326, 2, 64328, 2, 64435, 2, 64469, 2, 64831, 2, 64850, 2, 64913, 2, 64916, 2, 64969, 2, 65010, 2, 65021, 2, 65138, 2, 65142, 2, 65144, 2, 65278, 2, 65315, 2, 65340, 2, 65347, 2, 65372, 2, 65384, 2, 65472, 2, 65476, 2, 65481, 2, 65484, 2, 65489, 2, 65492, 2, 65497, 2, 65500, 2, 65502, 2, 2, 3, 13, 3, 15, 3, 40, 3, 42, 3, 60, 3, 62, 3, 63, 3, 65, 3, 79, 3, 82, 3, 95, 3, 130, 3, 252, 3, 642, 3, 670, 3, 674, 3, 722, 3, 770, 3, 801, 3, 818, 3, 834, 3, 836, 3, 843, 3, 850, 3, 887, 3, 898, 3, 927, 3, 930, 3, 965, 3, 970, 3, 977, 3, 1026, 3, 1183, 3, 1202, 3, 1237, 3, 1242, 3, 1277, 3, 1282, 3, 1321, 3, 1330, 3, 1381, 3, 1538, 3, 1848, 3, 1858, 3, 1879, 3, 1890, 3, 1897, 3, 2050, 3, 2055, 3, 2058, 3, 2058, 3, 2060, 3, 2103, 3, 2105, 3, 2106, 3, 2110, 3, 2110, 3, 2113, 3, 2135, 3, 2146, 3, 2168, 3, 2178, 3, 2208, 3, 2274, 3, 2292, 3, 2294, 3, 2295, 3, 2306, 3, 2327, 3, 2338, 3, 2363, 3, 2434, 3, 2489, 3, 2496, 3, 2497, 3, 2562, 3, 2562, 3, 2578, 3, 2581, 3, 2583, 3, 2585, 3, 2587, 3, 2613, 3, 2658, 3, 2686, 3, 2690, 3, 2718, 3, 2754, 3, 2761, 3, 2763, 3, 2790, 3, 2818, 3, 2871, 3, 2882, 3, 2903, 3, 2914, 3, 2932, 3, 2946, 3, 2963, 3, 3074, 3, 3146, 3, 3202, 3, 3252, 3, 3266, 3, 3316, 3, 4101, 3, 4153, 3, 4229, 3, 4273, 3, 4306, 3, 4330, 3, 4357, 3, 4392, 3, 4434, 3, 4468, 3, 4472, 3, 4472, 3, 4485, 3, 4532, 3, 4547, 3, 4550, 3, 4572, 3, 4572, 3, 4574, 3, 4574, 3, 4610, 3, 4627, 3, 4629, 3, 4653, 3, 4738, 3, 4744, 3, 4746, 3, 4746, 3, 4748, 3, 4751, 3, 4753, 3, 4767, 3, 4769, 3, 4778, 3, 4786, 3, 4832, 3, 4871, 3, 4878, 3, 4881, 3, 4882, 3, 4885, 3, 4906, 3, 4908, 3, 4914, 3, 4916, 3, 4917, 3, 4919, 3, 4923, 3, 4927, 3, 4927, 3, 4946, 3, 4946, 3, 4959, 3, 4963, 3, 5122, 3, 5174, 3, 5193, 3, 5196, 3, 5250, 3, 5297, 3, 5318, 3, 5319, 3, 5321, 3, 5321, 3, 5506, 3, 5552, 3, 5594, 3, 5597, 3, 5634, 3, 5681, 3, 5702, 3, 5702, 3, 5762, 3, 5804, 3, 5890, 3, 5915, 3, 6306, 3, 6369, 3, 6401, 3, 6401, 3, 6850, 3, 6906, 3, 7170, 3, 7178, 3, 7180, 3, 7216, 3, 7234, 3, 7234, 3, 7284, 3, 7313, 3, 8194, 3, 9115, 3, 9346, 3, 9541, 3, 12290, 3, 13360, 3, 17410, 3, 17992, 3, 26626, 3, 27194, 3, 27202, 3, 27232, 3, 27346, 3, 27375, 3, 27394, 3, 27441, 3, 27458, 3, 27461, 3, 27493, 3, 27513, 3, 27519, 3, 27537, 3, 28418, 3, 28486, 3, 28498, 3, 28498, 3, 28565, 3, 28577, 3, 28642, 3, 28642, 3, 28674, 3, 34798, 3, 34818, 3, 35572, 3, 45058, 3, 45059, 3, 48130, 3, 48236, 3, 48242, 3, 48254, 3, 48258, 3, 48266, 3, 48274, 3, 48283, 3, 54274, 3, 54358, 3, 54360, 3, 54430, 3, 54432, 3, 54433, 3, 54436, 3, 54436, 3, 54439, 3, 54440, 3, 54443, 3, 54446, 3, 54448, 3, 54459, 3, 54461, 3, 54461, 3, 54463, 3, 54469, 3, 54471, 3, 54535, 3, 54537, 3, 54540, 3, 54543, 3, 54550, 3, 54552, 3, 54558, 3, 54560, 3, 54587, 3, 54589, 3, 54592, 3, 54594, 3, 54598, 3, 54600, 3, 54600, 3, 54604, 3, 54610, 3, 54612, 3, 54951, 3, 54954, 3, 54978, 3, 54980, 3, 55004, 3, 55006, 3, 55036, 3, 55038, 3, 55062, 3, 55064, 3, 55094, 3, 55096, 3, 55120, 3, 55122, 3, 55152, 3, 55154, 3, 55178, 3, 55180, 3, 55210, 3, 55212, 3, 55236, 3, 55238, 3, 55245, 3, 59394, 3, 59590, 3, 59650, 3, 59717, 3, 60930, 3, 60933, 3, 60935, 3, 60961, 3, 60963, 3, 60964, 3, 60966, 3, 60966, 3, 60969, 3, 60969, 3, 60971, 3, 60980, 3, 60982, 3, 60985, 3, 60987, 3, 60987, 3, 60989, 3, 60989, 3, 60996, 3, 60996, 3, 61001, 3, 61001, 3, 61003, 3, 61003, 3, 61005, 3, 61005, 3, 61007, 3, 61009, 3, 61011, 3, 61012, 3, 61014, 3, 61014, 3, 61017, 3, 61017, 3, 61019, 3, 61019, 3, 61021, 3, 61021, 3, 61023, 3, 61023, 3, 61025, 3, 61025, 3, 61027, 3, 61028, 3, 61030, 3, 61030, 3, 61033, 3, 61036, 3, 61038, 3, 61044, 3, 61046, 3, 61049, 3, 61051, 3, 61054, 3, 61056, 3, 61056, 3, 61058, 3, 61067, 3, 61069, 3, 61085, 3, 61091, 3, 61093, 3, 61095, 3, 61099, 3, 61101, 3, 61117, 3, 2, 4, 42712, 4, 42754, 4, 46902, 4, 46914, 4, 47135, 4, 47138, 4, 52899, 4, 63490, 4, 64031, 4, 912, 2, 4, 3, 2, 2, 2, 2, 6, 3, 2, 2, 2, 2, 8, 3, 2, 2, 2, 2, 10, 3, 2, 2, 2, 2, 12, 3, 2, 2, 2, 2, 14, 3, 2, 2, 2, 2, 16, 3, 2, 2, 2, 2, 18, 3, 2, 2, 2, 2, 20, 3, 2, 2, 2, 2, 22, 3, 2, 2, 2, 2, 24, 3, 2, 2, 2, 2, 26, 3, 2, 2, 2, 2, 28, 3, 2, 2, 2, 2, 30, 3, 2, 2, 2, 2, 32, 3, 2, 2, 2, 2, 34, 3, 2, 2, 2, 2, 36, 3, 2, 2, 2, 2, 38, 3, 2, 2, 2, 2, 40, 3, 2, 2, 2, 2, 42, 3, 2, 2, 2, 2, 44, 3, 2, 2, 2, 2, 46, 3, 2, 2, 2, 2, 48, 3, 2, 2, 2, 2, 50, 3, 2, 2, 2, 2, 52, 3, 2, 2, 2, 2, 54, 3, 2, 2, 2, 2, 56, 3, 2, 2, 2, 2, 58, 3, 2, 2, 2, 2, 60, 3, 2, 2, 2, 2, 62, 3, 2, 2, 2, 2, 64, 3, 2, 2, 2, 2, 66, 3, 2, 2, 2, 2, 68, 3, 2, 2, 2, 2, 70, 3, 2, 2, 2, 2, 72, 3, 2, 2, 2, 2, 74, 3, 2, 2, 2, 2, 76, 3, 2, 2, 2, 2, 78, 3, 2, 2, 2, 2, 80, 3, 2, 2, 2, 2, 82, 3, 2, 2, 2, 2, 84, 3, 2, 2, 2, 2, 86, 3, 2, 2, 2, 2, 88, 3, 2, 2, 2, 2, 90, 3, 2, 2, 2, 2, 92, 3, 2, 2, 2, 2, 94, 3, 2, 2, 2, 2, 96, 3, 2, 2, 2, 2, 98, 3, 2, 2, 2, 2, 100, 3, 2, 2, 2, 2, 102, 3, 2, 2, 2, 2, 104, 3, 2, 2, 2, 2, 106, 3, 2, 2, 2, 2, 108, 3, 2, 2, 2, 2, 110, 3, 2, 2, 2, 2, 112, 3, 2, 2, 2, 2, 114, 3, 2, 2, 2, 2, 116, 3, 2, 2, 2, 2, 118, 3, 2, 2, 2, 2, 120, 3, 2, 2, 2, 2, 122, 3, 2, 2, 2, 2, 124, 3, 2, 2, 2, 2, 126, 3, 2, 2, 2, 2, 128, 3, 2, 2, 2, 2, 130, 3, 2, 2, 2, 2, 132, 3, 2, 2, 2, 2, 134, 3, 2, 2, 2, 2, 136, 3, 2, 2, 2, 2, 138, 3, 2, 2, 2, 2, 140, 3, 2, 2, 2, 2, 142, 3, 2, 2, 2, 2, 144, 3, 2, 2, 2, 2, 150, 3, 2, 2, 2, 2, 154, 3, 2, 2, 2, 2, 156, 3, 2, 2, 2, 2, 158, 3, 2, 2, 2, 2, 160, 3, 2, 2, 2, 2, 162, 3, 2, 2, 2, 2, 164, 3, 2, 2, 2, 2, 166, 3, 2, 2, 2, 2, 168, 3, 2, 2, 2, 2, 170, 3, 2, 2, 2, 2, 172, 3, 2, 2, 2, 2, 174, 3, 2, 2, 2, 2, 176, 3, 2, 2, 2, 2, 178, 3, 2, 2, 2, 3, 200, 3, 2, 2, 2, 3, 202, 3, 2, 2, 2, 3, 204, 3, 2, 2, 2, 3, 206, 3, 2, 2, 2, 3, 208, 3, 2, 2, 2, 4, 210, 3, 2, 2, 2, 6, 218, 3, 2, 2, 2, 8, 226, 3, 2, 2, 2, 10, 231, 3, 2, 2, 2, 12, 241, 3, 2, 2, 2, 14, 248, 3, 2, 2, 2, 16, 253, 3, 2, 2, 2, 18, 259, 3, 2, 2, 2, 20, 262, 3, 2, 2, 2, 22, 266, 3, 2, 2, 2, 24, 273, 3, 2, 2, 2, 26, 278, 3, 2, 2, 2, 28, 283, 3, 2, 2, 2, 30, 288, 3, 2, 2, 2, 32, 296, 3, 2, 2, 2, 34, 303, 3, 2, 2, 2, 36, 309, 3, 2, 2, 2, 38, 323, 3, 2, 2, 2, 40, 326, 3, 2, 2, 2, 42, 332, 3, 2, 2, 2, 44, 337, 3, 2, 2, 2, 46, 348, 3, 2, 2, 2, 48, 352, 3, 2, 2, 2, 50, 359, 3, 2, 2, 2, 52, 368, 3, 2, 2, 2, 54, 372, 3, 2, 2, 2, 56, 378, 3, 2, 2, 2, 58, 388, 3, 2, 2, 2, 60, 390, 3, 2, 2, 2, 62, 394, 3, 2, 2, 2, 64, 396, 3, 2, 2, 2, 66, 400, 3, 2, 2, 2, 68, 402, 3, 2, 2, 2, 70, 406, 3, 2, 2, 2, 72, 408, 3, 2, 2, 2, 74, 410, 3, 2, 2, 2, 76, 412, 3, 2, 2, 2, 78, 414, 3, 2, 2, 2, 80, 416, 3, 2, 2, 2, 82, 421, 3, 2, 2, 2, 84, 426, 3, 2, 2, 2, 86, 429, 3, 2, 2, 2, 88, 433, 3, 2, 2, 2, 90, 436, 3, 2, 2, 2, 92, 439, 3, 2, 2, 2, 94, 442, 3, 2, 2, 2, 96, 445, 3, 2, 2, 2, 98, 447, 3, 2, 2, 2, 100, 450, 3, 2, 2, 2, 102, 452, 3, 2, 2, 2, 104, 455, 3, 2, 2, 2, 106, 457, 3, 2, 2, 2, 108, 459, 3, 2, 2, 2, 110, 461, 3, 2, 2, 2, 112, 464, 3, 2, 2, 2, 114, 467, 3, 2, 2, 2, 116, 470, 3, 2, 2, 2, 118, 472, 3, 2, 2, 2, 120, 474, 3, 2, 2, 2, 122, 476, 3, 2, 2, 2, 124, 478, 3, 2, 2, 2, 126, 480, 3, 2, 2, 2, 128, 482, 3, 2, 2, 2, 130, 484, 3, 2, 2, 2, 132, 498, 3, 2, 2, 2, 134, 502, 3, 2, 2, 2, 136, 514, 3, 2, 2, 2, 138, 528, 3, 2, 2, 2, 140, 542, 3, 2, 2, 2, 142, 562, 3, 2, 2, 2, 144, 564, 3, 2, 2, 2, 146, 600, 3, 2, 2, 2, 148, 602, 3, 2, 2, 2, 150, 613, 3, 2, 2, 2, 152, 619, 3, 2, 2, 2, 154, 626, 3, 2, 2, 2, 156, 632, 3, 2, 2, 2, 158, 634, 3, 2, 2, 2, 160, 639, 3, 2, 2, 2, 162, 644, 3, 2, 2, 2, 164, 651, 3, 2, 2, 2, 166, 662, 3, 2, 2, 2, 168, 673, 3, 2, 2, 2, 170, 686, 3, 2, 2, 2, 172, 692, 3, 2, 2, 2, 174, 707, 3, 2, 2, 2, 176, 713, 3, 2, 2, 2, 178, 738, 3, 2, 2, 2, 180, 744, 3, 2, 2, 2, 182, 746, 3, 2, 2, 2, 184, 774, 3, 2, 2, 2, 186, 784, 3, 2, 2, 2, 188, 786, 3, 2, 2, 2, 190, 788, 3, 2, 2, 2, 192, 790, 3, 2, 2, 2, 194, 798, 3, 2, 2, 2, 196, 800, 3, 2, 2, 2, 198, 802, 3, 2, 2, 2, 200, 805, 3, 2, 2, 2, 202, 811, 3, 2, 2, 2, 204, 825, 3, 2, 2, 2, 206, 854, 3, 2, 2, 2, 208, 858, 3, 2, 2, 2, 210, 211, 7, 100, 2, 2, 211, 212, 7, 116, 2, 2, 212, 213, 7, 103, 2, 2, 213, 214, 7, 99, 2, 2, 214, 215, 7, 109, 2, 2, 215, 216, 3, 2, 2, 2, 216, 217, 8, 2, 2, 2, 217, 5, 3, 2, 2, 2, 218, 219, 7, 102, 2, 2, 219, 220, 7, 103, 2, 2, 220, 221, 7, 104, 2, 2, 221, 222, 7, 99, 2, 2, 222, 223, 7, 119, 2, 2, 223, 224, 7, 110, 2, 2, 224, 225, 7, 118, 2, 2, 225, 7, 3, 2, 2, 2, 226, 227, 7, 104, 2, 2, 227, 228, 7, 119, 2, 2, 228, 229, 7, 112, 2, 2, 229, 230, 7, 101, 2, 2, 230, 9, 3, 2, 2, 2, 231, 232, 7, 107, 2, 2, 232, 233, 7, 112, 2, 2, 233, 234, 7, 118, 2, 2, 234, 235, 7, 103, 2, 2, 235, 236, 7, 116, 2, 2, 236, 237, 7, 104, 2, 2, 237, 238, 7, 99, 2, 2, 238, 239, 7, 101, 2, 2, 239, 240, 7, 103, 2, 2, 240, 11, 3, 2, 2, 2, 241, 242, 7, 117, 2, 2, 242, 243, 7, 103, 2, 2, 243, 244, 7, 110, 2, 2, 244, 245, 7, 103, 2, 2, 245, 246, 7, 101, 2, 2, 246, 247, 7, 118, 2, 2, 247, 13, 3, 2, 2, 2, 248, 249, 7, 101, 2, 2, 249, 250, 7, 99, 2, 2, 250, 251, 7, 117, 2, 2, 251, 252, 7, 103, 2, 2, 252, 15, 3, 2, 2, 2, 253, 254, 7, 102, 2, 2, 254, 255, 7, 103, 2, 2, 255, 256, 7, 104, 2, 2, 256, 257, 7, 103, 2, 2, 257, 258, 7, 116, 2, 2, 258, 17, 3, 2, 2, 2, 259, 260, 7, 105, 2, 2, 260, 261, 7, 113, 2, 2, 261, 19, 3, 2, 2, 2, 262, 263, 7, 111, 2, 2, 263, 264, 7, 99, 2, 2, 264, 265, 7, 114, 2, 2, 265, 21, 3, 2, 2, 2, 266, 267, 7, 117, 2, 2, 267, 268, 7, 118, 2, 2, 268, 269, 7, 116, 2, 2, 269, 270, 7, 119, 2, 2, 270, 271, 7, 101, 2, 2, 271, 272, 7, 118, 2, 2, 272, 23, 3, 2, 2, 2, 273, 274, 7, 101, 2, 2, 274, 275, 7, 106, 2, 2, 275, 276, 7, 99, 2, 2, 276, 277, 7, 112, 2, 2, 277, 25, 3, 2, 2, 2, 278, 279, 7, 103, 2, 2, 279, 280, 7, 110, 2, 2, 280, 281, 7, 117, 2, 2, 281, 282, 7, 103, 2, 2, 282, 27, 3, 2, 2, 2, 283, 284, 7, 105, 2, 2, 284, 285, 7, 113, 2, 2, 285, 286, 7, 118, 2, 2, 286, 287, 7, 113, 2, 2, 287, 29, 3, 2, 2, 2, 288, 289, 7, 114, 2, 2, 289, 290, 7, 99, 2, 2, 290, 291, 7, 101, 2, 2, 291, 292, 7, 109, 2, 2, 292, 293, 7, 99, 2, 2, 293, 294, 7, 105, 2, 2, 294, 295, 7, 103, 2, 2, 295, 31, 3, 2, 2, 2, 296, 297, 7, 117, 2, 2, 297, 298, 7, 121, 2, 2, 298, 299, 7, 107, 2, 2, 299, 300, 7, 118, 2, 2, 300, 301, 7, 101, 2, 2, 301, 302, 7, 106, 2, 2, 302, 33, 3, 2, 2, 2, 303, 304, 7, 101, 2, 2, 304, 305, 7, 113, 2, 2, 305, 306, 7, 112, 2, 2, 306, 307, 7, 117, 2, 2, 307, 308, 7, 118, 2, 2, 308, 35, 3, 2, 2, 2, 309, 310, 7, 104, 2, 2, 310, 311, 7, 99, 2, 2, 311, 312, 7, 110, 2, 2, 312, 313, 7, 110, 2, 2, 313, 314, 7, 118, 2, 2, 314, 315, 7, 106, 2, 2, 315, 316, 7, 116, 2, 2, 316, 317, 7, 113, 2, 2, 317, 318, 7, 119, 2, 2, 318, 319, 7, 105, 2, 2, 319, 320, 7, 106, 2, 2, 320, 321, 3, 2, 2, 2, 321, 322, 8, 18, 2, 2, 322, 37, 3, 2, 2, 2, 323, 324, 7, 107, 2, 2, 324, 325, 7, 104, 2, 2, 325, 39, 3, 2, 2, 2, 326, 327, 7, 116, 2, 2, 327, 328, 7, 99, 2, 2, 328, 329, 7, 112, 2, 2, 329, 330, 7, 105, 2, 2, 330, 331, 7, 103, 2, 2, 331, 41, 3, 2, 2, 2, 332, 333, 7, 118, 2, 2, 333, 334, 7, 123, 2, 2, 334, 335, 7, 114, 2, 2, 335, 336, 7, 103, 2, 2, 336, 43, 3, 2, 2, 2, 337, 338, 7, 101, 2, 2, 338, 339, 7, 113, 2, 2, 339, 340, 7, 112, 2, 2, 340, 341, 7, 118, 2, 2, 341, 342, 7, 107, 2, 2, 342, 343, 7, 112, 2, 2, 343, 344, 7, 119, 2, 2, 344, 345, 7, 103, 2, 2, 345, 346, 3, 2, 2, 2, 346, 347, 8, 22, 2, 2, 347, 45, 3, 2, 2, 2, 348, 349, 7, 104, 2, 2, 349, 350, 7, 113, 2, 2, 350, 351, 7, 116, 2, 2, 351, 47, 3, 2, 2, 2, 352, 353, 7, 107, 2, 2, 353, 354, 7, 111, 2, 2, 354, 355, 7, 114, 2, 2, 355, 356, 7, 113, 2, 2, 356, 357, 7, 116, 2, 2, 357, 358, 7, 118, 2, 2, 358, 49, 3, 2, 2, 2, 359, 360, 7, 116, 2, 2, 360, 361, 7, 103, 2, 2, 361, 362, 7, 118, 2, 2, 362, 363, 7, 119, 2, 2, 363, 364, 7, 116, 2, 2, 364, 365, 7, 112, 2, 2, 365, 366, 3, 2, 2, 2, 366, 367, 8, 25, 2, 2, 367, 51, 3, 2, 2, 2, 368, 369, 7, 120, 2, 2, 369, 370, 7, 99, 2, 2, 370, 371, 7, 116, 2, 2, 371, 53, 3, 2, 2, 2, 372, 373, 7, 112, 2, 2, 373, 374, 7, 107, 2, 2, 374, 375, 7, 110, 2, 2, 375, 376, 3, 2, 2, 2, 376, 377, 8, 27, 2, 2, 377, 55, 3, 2, 2, 2, 378, 383, 5, 194, 97, 2, 379, 382, 5, 194, 97, 2, 380, 382, 5, 196, 98, 2, 381, 379, 3, 2, 2, 2, 381, 380, 3, 2, 2, 2, 382, 385, 3, 2, 2, 2, 383, 381, 3, 2, 2, 2, 383, 384, 3, 2, 2, 2, 384, 386, 3, 2, 2, 2, 385, 383, 3, 2, 2, 2, 386, 387, 8, 28, 2, 2, 387, 57, 3, 2, 2, 2, 388, 389, 7, 42, 2, 2, 389, 59, 3, 2, 2, 2, 390, 391, 7, 43, 2, 2, 391, 392, 3, 2, 2, 2, 392, 393, 8, 30, 2, 2, 393, 61, 3, 2, 2, 2, 394, 395, 7, 125, 2, 2, 395, 63, 3, 2, 2, 2, 396, 397, 7, 127, 2, 2, 397, 398, 3, 2, 2, 2, 398, 399, 8, 32, 2, 2, 399, 65, 3, 2, 2, 2, 400, 401, 7, 93, 2, 2, 401, 67, 3, 2, 2, 2, 402, 403, 7, 95, 2, 2, 403, 404, 3, 2, 2, 2, 404, 405, 8, 34, 2, 2, 405, 69, 3, 2, 2, 2, 406, 407, 7, 63, 2, 2, 407, 71, 3, 2, 2, 2, 408, 409, 7, 46, 2, 2, 409, 73, 3, 2, 2, 2, 410, 411, 7, 61, 2, 2, 411, 75, 3, 2, 2, 2, 412, 413, 7, 60, 2, 2, 413, 77, 3, 2, 2, 2, 414, 415, 7, 48, 2, 2, 415, 79, 3, 2, 2, 2, 416, 417, 7, 45, 2, 2, 417, 418, 7, 45, 2, 2, 418, 419, 3, 2, 2, 2, 419, 420, 8, 40, 2, 2, 420, 81, 3, 2, 2, 2, 421, 422, 7, 47, 2, 2, 422, 423, 7, 47, 2, 2, 423, 424, 3, 2, 2, 2, 424, 425, 8, 41, 2, 2, 425, 83, 3, 2, 2, 2, 426, 427, 7, 60, 2, 2, 427, 428, 7, 63, 2, 2, 428, 85, 3, 2, 2, 2, 429, 430, 7, 48, 2, 2, 430, 431, 7, 48, 2, 2, 431, 432, 7, 48, 2, 2, 432, 87, 3, 2, 2, 2, 433, 434, 7, 126, 2, 2, 434, 435, 7, 126, 2, 2, 435, 89, 3, 2, 2, 2, 436, 437, 7, 40, 2, 2, 437, 438, 7, 40, 2, 2, 438, 91, 3, 2, 2, 2, 439, 440, 7, 63, 2, 2, 440, 441, 7, 63, 2, 2, 441, 93, 3, 2, 2, 2, 442, 443, 7, 35, 2, 2, 443, 444, 7, 63, 2, 2, 444, 95, 3, 2, 2, 2, 445, 446, 7, 62, 2, 2, 446, 97, 3, 2, 2, 2, 447, 448, 7, 62, 2, 2, 448, 449, 7, 63, 2, 2, 449, 99, 3, 2, 2, 2, 450, 451, 7, 64, 2, 2, 451, 101, 3, 2, 2, 2, 452, 453, 7, 64, 2, 2, 453, 454, 7, 63, 2, 2, 454, 103, 3, 2, 2, 2, 455, 456, 7, 126, 2, 2, 456, 105, 3, 2, 2, 2, 457, 458, 7, 49, 2, 2, 458, 107, 3, 2, 2, 2, 459, 460, 7, 39, 2, 2, 460, 109, 3, 2, 2, 2, 461, 462, 7, 62, 2, 2, 462, 463, 7, 62, 2, 2, 463, 111, 3, 2, 2, 2, 464, 465, 7, 64, 2, 2, 465, 466, 7, 64, 2, 2, 466, 113, 3, 2, 2, 2, 467, 468, 7, 40, 2, 2, 468, 469, 7, 96, 2, 2, 469, 115, 3, 2, 2, 2, 470, 471, 7, 128, 2, 2, 471, 117, 3, 2, 2, 2, 472, 473, 7, 35, 2, 2, 473, 119, 3, 2, 2, 2, 474, 475, 7, 45, 2, 2, 475, 121, 3, 2, 2, 2, 476, 477, 7, 47, 2, 2, 477, 123, 3, 2, 2, 2, 478, 479, 7, 96, 2, 2, 479, 125, 3, 2, 2, 2, 480, 481, 7, 44, 2, 2, 481, 127, 3, 2, 2, 2, 482, 483, 7, 40, 2, 2, 483, 129, 3, 2, 2, 2, 484, 485, 7, 62, 2, 2, 485, 486, 7, 47, 2, 2, 486, 131, 3, 2, 2, 2, 487, 499, 7, 50, 2, 2, 488, 495, 9, 2, 2, 2, 489, 491, 7, 97, 2, 2, 490, 489, 3, 2, 2, 2, 490, 491, 3, 2, 2, 2, 491, 492, 3, 2, 2, 2, 492, 494, 9, 3, 2, 2, 493, 490, 3, 2, 2, 2, 494, 497, 3, 2, 2, 2, 495, 493, 3, 2, 2, 2, 495, 496, 3, 2, 2, 2, 496, 499, 3, 2, 2, 2, 497, 495, 3, 2, 2, 2, 498, 487, 3, 2, 2, 2, 498, 488, 3, 2, 2, 2, 499, 500, 3, 2, 2, 2, 500, 501, 8, 66, 2, 2, 501, 133, 3, 2, 2, 2, 502, 503, 7, 50, 2, 2, 503, 508, 9, 4, 2, 2, 504, 506, 7, 97, 2, 2, 505, 504, 3, 2, 2, 2, 505, 506, 3, 2, 2, 2, 506, 507, 3, 2, 2, 2, 507, 509, 5, 190, 95, 2, 508, 505, 3, 2, 2, 2, 509, 510, 3, 2, 2, 2, 510, 508, 3, 2, 2, 2, 510, 511, 3, 2, 2, 2, 511, 512, 3, 2, 2, 2, 512, 513, 8, 67, 2, 2, 513, 135, 3, 2, 2, 2, 514, 516, 7, 50, 2, 2, 515, 517, 9, 5, 2, 2, 516, 515, 3, 2, 2, 2, 516, 517, 3, 2, 2, 2, 517, 522, 3, 2, 2, 2, 518, 520, 7, 97, 2, 2, 519, 518, 3, 2, 2, 2, 519, 520, 3, 2, 2, 2, 520, 521, 3, 2, 2, 2, 521, 523, 5, 186, 93, 2, 522, 519, 3, 2, 2, 2, 523, 524, 3, 2, 2, 2, 524, 522, 3, 2, 2, 2, 524, 525, 3, 2, 2, 2, 525, 526, 3, 2, 2, 2, 526, 527, 8, 68, 2, 2, 527, 137, 3, 2, 2, 2, 528, 529, 7, 50, 2, 2, 529, 534, 9, 6, 2, 2, 530, 532, 7, 97, 2, 2, 531, 530, 3, 2, 2, 2, 531, 532, 3, 2, 2, 2, 532, 533, 3, 2, 2, 2, 533, 535, 5, 188, 94, 2, 534, 531, 3, 2, 2, 2, 535, 536, 3, 2, 2, 2, 536, 534, 3, 2, 2, 2, 536, 537, 3, 2, 2, 2, 537, 538, 3, 2, 2, 2, 538, 539, 8, 69, 2, 2, 539, 139, 3, 2, 2, 2, 540, 543, 5, 142, 71, 2, 541, 543, 5, 144, 72, 2, 542, 540, 3, 2, 2, 2, 542, 541, 3, 2, 2, 2, 543, 544, 3, 2, 2, 2, 544, 545, 8, 70, 2, 2, 545, 141, 3, 2, 2, 2, 546, 555, 5, 184, 92, 2, 547, 549, 7, 48, 2, 2, 548, 550, 5, 184, 92, 2, 549, 548, 3, 2, 2, 2, 549, 550, 3, 2, 2, 2, 550, 552, 3, 2, 2, 2, 551, 553, 5, 192, 96, 2, 552, 551, 3, 2, 2, 2, 552, 553, 3, 2, 2, 2, 553, 556, 3, 2, 2, 2, 554, 556, 5, 192, 96, 2, 555, 547, 3, 2, 2, 2, 555, 554, 3, 2, 2, 2, 556, 563, 3, 2, 2, 2, 557, 558, 7, 48, 2, 2, 558, 560, 5, 184, 92, 2, 559, 561, 5, 192, 96, 2, 560, 559, 3, 2, 2, 2, 560, 561, 3, 2, 2, 2, 561, 563, 3, 2, 2, 2, 562, 546, 3, 2, 2, 2, 562, 557, 3, 2, 2, 2, 563, 143, 3, 2, 2, 2, 564, 565, 7, 50, 2, 2, 565, 566, 9, 6, 2, 2, 566, 567, 5, 146, 73, 2, 567, 568, 5, 148, 74, 2, 568, 145, 3, 2, 2, 2, 569, 571, 7, 97, 2, 2, 570, 569, 3, 2, 2, 2, 570, 571, 3, 2, 2, 2, 571, 572, 3, 2, 2, 2, 572, 574, 5, 188, 94, 2, 573, 570, 3, 2, 2, 2, 574, 575, 3, 2, 2, 2, 575, 573, 3, 2, 2, 2, 575, 576, 3, 2, 2, 2, 576, 587, 3, 2, 2, 2, 577, 584, 7, 48, 2, 2, 578, 580, 7, 97, 2, 2, 579, 578, 3, 2, 2, 2, 579, 580, 3, 2, 2, 2, 580, 581, 3, 2, 2, 2, 581, 583, 5, 188, 94, 2, 582, 579, 3, 2, 2, 2, 583, 586, 3, 2, 2, 2, 584, 582, 3, 2, 2, 2, 584, 585, 3, 2, 2, 2, 585, 588, 3, 2, 2, 2, 586, 584, 3, 2, 2, 2, 587, 577, 3, 2, 2, 2, 587, 588, 3, 2, 2, 2, 588, 601, 3, 2, 2, 2, 589, 590, 7, 48, 2, 2, 590, 597, 5, 188, 94, 2, 591, 593, 7, 97, 2, 2, 592, 591, 3, 2, 2, 2, 592, 593, 3, 2, 2, 2, 593, 594, 3, 2, 2, 2, 594, 596, 5, 188, 94, 2, 595, 592, 3, 2, 2, 2, 596, 599, 3, 2, 2, 2, 597, 595, 3, 2, 2, 2, 597, 598, 3, 2, 2, 2, 598, 601, 3, 2, 2, 2, 599, 597, 3, 2, 2, 2, 600, 573, 3, 2, 2, 2, 600, 589, 3, 2, 2, 2, 601, 147, 3, 2, 2, 2, 602, 604, 9, 7, 2, 2, 603, 605, 9, 8, 2, 2, 604, 603, 3, 2, 2, 2, 604, 605, 3, 2, 2, 2, 605, 606, 3, 2, 2, 2, 606, 607, 5, 184, 92, 2, 607, 149, 3, 2, 2, 2, 608, 614, 5, 132, 66, 2, 609, 614, 5, 134, 67, 2, 610, 614, 5, 136, 68, 2, 611, 614, 5, 138, 69, 2, 612, 614, 5, 140, 70, 2, 613, 608, 3, 2, 2, 2, 613, 609, 3, 2, 2, 2, 613, 610, 3, 2, 2, 2, 613, 611, 3, 2, 2, 2, 613, 612, 3, 2, 2, 2, 614, 615, 3, 2, 2, 2, 615, 616, 7, 107, 2, 2, 616, 617, 3, 2, 2, 2, 617, 618, 8, 75, 2, 2, 618, 151, 3, 2, 2, 2, 619, 622, 7, 41, 2, 2, 620, 623, 5, 180, 90, 2, 621, 623, 5, 156, 78, 2, 622, 620, 3, 2, 2, 2, 622, 621, 3, 2, 2, 2, 623, 624, 3, 2, 2, 2, 624, 625, 7, 41, 2, 2, 625, 153, 3, 2, 2, 2, 626, 627, 5, 152, 76, 2, 627, 628, 3, 2, 2, 2, 628, 629, 8, 77, 2, 2, 629, 155, 3, 2, 2, 2, 630, 633, 5, 158, 79, 2, 631, 633, 5, 160, 80, 2, 632, 630, 3, 2, 2, 2, 632, 631, 3, 2, 2, 2, 633, 157, 3, 2, 2, 2, 634, 635, 7, 94, 2, 2, 635, 636, 5, 186, 93, 2, 636, 637, 5, 186, 93, 2, 637, 638, 5, 186, 93, 2, 638, 159, 3, 2, 2, 2, 639, 640, 7, 94, 2, 2, 640, 641, 7, 122, 2, 2, 641, 642, 5, 188, 94, 2, 642, 643, 5, 188, 94, 2, 643, 161, 3, 2, 2, 2, 644, 645, 7, 94, 2, 2, 645, 646, 7, 119, 2, 2, 646, 647, 5, 188, 94, 2, 647, 648, 5, 188, 94, 2, 648, 649, 5, 188, 94, 2, 649, 650, 5, 188, 94, 2, 650, 163, 3, 2, 2, 2, 651, 652, 7, 94, 2, 2, 652, 653, 7, 87, 2, 2, 653, 654, 5, 188, 94, 2, 654, 655, 5, 188, 94, 2, 655, 656, 5, 188, 94, 2, 656, 657, 5, 188, 94, 2, 657, 658, 5, 188, 94, 2, 658, 659, 5, 188, 94, 2, 659, 660, 5, 188, 94, 2, 660, 661, 5, 188, 94, 2, 661, 165, 3, 2, 2, 2, 662, 666, 7, 98, 2, 2, 663, 665, 10, 9, 2, 2, 664, 663, 3, 2, 2, 2, 665, 668, 3, 2, 2, 2, 666, 664, 3, 2, 2, 2, 666, 667, 3, 2, 2, 2, 667, 669, 3, 2, 2, 2, 668, 666, 3, 2, 2, 2, 669, 670, 7, 98, 2, 2, 670, 671, 3, 2, 2, 2, 671, 672, 8, 83, 2, 2, 672, 167, 3, 2, 2, 2, 673, 678, 7, 36, 2, 2, 674, 677, 10, 10, 2, 2, 675, 677, 5, 182, 91, 2, 676, 674, 3, 2, 2, 2, 676, 675, 3, 2, 2, 2, 677, 680, 3, 2, 2, 2, 678, 676, 3, 2, 2, 2, 678, 679, 3, 2, 2, 2, 679, 681, 3, 2, 2, 2, 680, 678, 3, 2, 2, 2, 681, 682, 7, 36, 2, 2, 682, 683, 3, 2, 2, 2, 683, 684, 8, 84, 2, 2, 684, 169, 3, 2, 2, 2, 685, 687, 9, 11, 2, 2, 686, 685, 3, 2, 2, 2, 687, 688, 3, 2, 2, 2, 688, 686, 3, 2, 2, 2, 688, 689, 3, 2, 2, 2, 689, 690, 3, 2, 2, 2, 690, 691, 8, 85, 3, 2, 691, 171, 3, 2, 2, 2, 692, 693, 7, 49, 2, 2, 693, 694, 7, 44, 2, 2, 694, 698, 3, 2, 2, 2, 695, 697, 11, 2, 2, 2, 696, 695, 3, 2, 2, 2, 697, 700, 3, 2, 2, 2, 698, 699, 3, 2, 2, 2, 698, 696, 3, 2, 2, 2, 699, 701, 3, 2, 2, 2, 700, 698, 3, 2, 2, 2, 701, 702, 7, 44, 2, 2, 702, 703, 7, 49, 2, 2, 703, 704, 3, 2, 2, 2, 704, 705, 8, 86, 3, 2, 705, 173, 3, 2, 2, 2, 706, 708, 9, 12, 2, 2, 707, 706, 3, 2, 2, 2, 708, 709, 3, 2, 2, 2, 709, 707, 3, 2, 2, 2, 709, 710, 3, 2, 2, 2, 710, 711, 3, 2, 2, 2, 711, 712, 8, 87, 3, 2, 712, 175, 3, 2, 2, 2, 713, 714, 7, 49, 2, 2, 714, 715, 7, 49, 2, 2, 715, 719, 3, 2, 2, 2, 716, 718, 10, 12, 2, 2, 717, 716, 3, 2, 2, 2, 718, 721, 3, 2, 2, 2, 719, 717, 3, 2, 2, 2, 719, 720, 3, 2, 2, 2, 720, 722, 3, 2, 2, 2, 721, 719, 3, 2, 2, 2, 722, 723, 8, 88, 3, 2, 723, 177, 3, 2, 2, 2, 724, 726, 7, 15, 2, 2, 725, 724, 3, 2, 2, 2, 725, 726, 3, 2, 2, 2, 726, 727, 3, 2, 2, 2, 727, 739, 7, 12, 2, 2, 728, 730, 7, 15, 2, 2, 729, 728, 3, 2, 2, 2, 730, 731, 3, 2, 2, 2, 731, 729, 3, 2, 2, 2, 731, 732, 3, 2, 2, 2, 732, 739, 3, 2, 2, 2, 733, 735, 7, 12, 2, 2, 734, 733, 3, 2, 2, 2, 735, 736, 3, 2, 2, 2, 736, 734, 3, 2, 2, 2, 736, 737, 3, 2, 2, 2, 737, 739, 3, 2, 2, 2, 738, 725, 3, 2, 2, 2, 738, 729, 3, 2, 2, 2, 738, 734, 3, 2, 2, 2, 739, 179, 3, 2, 2, 2, 740, 745, 10, 13, 2, 2, 741, 745, 5, 162, 81, 2, 742, 745, 5, 164, 82, 2, 743, 745, 5, 182, 91, 2, 744, 740, 3, 2, 2, 2, 744, 741, 3, 2, 2, 2, 744, 742, 3, 2, 2, 2, 744, 743, 3, 2, 2, 2, 745, 181, 3, 2, 2, 2, 746, 772, 7, 94, 2, 2, 747, 748, 7, 119, 2, 2, 748, 749, 5, 188, 94, 2, 749, 750, 5, 188, 94, 2, 750, 751, 5, 188, 94, 2, 751, 752, 5, 188, 94, 2, 752, 773, 3, 2, 2, 2, 753, 754, 7, 87, 2, 2, 754, 755, 5, 188, 94, 2, 755, 756, 5, 188, 94, 2, 756, 757, 5, 188, 94, 2, 757, 758, 5, 188, 94, 2, 758, 759, 5, 188, 94, 2, 759, 760, 5, 188, 94, 2, 760, 761, 5, 188, 94, 2, 761, 762, 5, 188, 94, 2, 762, 773, 3, 2, 2, 2, 763, 773, 9, 14, 2, 2, 764, 765, 5, 186, 93, 2, 765, 766, 5, 186, 93, 2, 766, 767, 5, 186, 93, 2, 767, 773, 3, 2, 2, 2, 768, 769, 7, 122, 2, 2, 769, 770, 5, 188, 94, 2, 770, 771, 5, 188, 94, 2, 771, 773, 3, 2, 2, 2, 772, 747, 3, 2, 2, 2, 772, 753, 3, 2, 2, 2, 772, 763, 3, 2, 2, 2, 772, 764, 3, 2, 2, 2, 772, 768, 3, 2, 2, 2, 773, 183, 3, 2, 2, 2, 774, 781, 9, 3, 2, 2, 775, 777, 7, 97, 2, 2, 776, 775, 3, 2, 2, 2, 776, 777, 3, 2, 2, 2, 777, 778, 3, 2, 2, 2, 778, 780, 9, 3, 2, 2, 779, 776, 3, 2, 2, 2, 780, 783, 3, 2, 2, 2, 781, 779, 3, 2, 2, 2, 781, 782, 3, 2, 2, 2, 782, 185, 3, 2, 2, 2, 783, 781, 3, 2, 2, 2, 784, 785, 9, 15, 2, 2, 785, 187, 3, 2, 2, 2, 786, 787, 9, 16, 2, 2, 787, 189, 3, 2, 2, 2, 788, 789, 9, 17, 2, 2, 789, 191, 3, 2, 2, 2, 790, 792, 9, 18, 2, 2, 791, 793, 9, 8, 2, 2, 792, 791, 3, 2, 2, 2, 792, 793, 3, 2, 2, 2, 793, 794, 3, 2, 2, 2, 794, 795, 5, 184, 92, 2, 795, 193, 3, 2, 2, 2, 796, 799, 5, 198, 99, 2, 797, 799, 7, 97, 2, 2, 798, 796, 3, 2, 2, 2, 798, 797, 3, 2, 2, 2, 799, 195, 3, 2, 2, 2, 800, 801, 9, 19, 2, 2, 801, 197, 3, 2, 2, 2, 802, 803, 9, 20, 2, 2, 803, 199, 3, 2, 2, 2, 804, 806, 9, 11, 2, 2, 805, 804, 3, 2, 2, 2, 806, 807, 3, 2, 2, 2, 807, 805, 3, 2, 2, 2, 807, 808, 3, 2, 2, 2, 808, 809, 3, 2, 2, 2, 809, 810, 8, 100, 3, 2, 810, 201, 3, 2, 2, 2, 811, 812, 7, 49, 2, 2, 812, 813, 7, 44, 2, 2, 813, 817, 3, 2, 2, 2, 814, 816, 10, 12, 2, 2, 815, 814, 3, 2, 2, 2, 816, 819, 3, 2, 2, 2, 817, 818, 3, 2, 2, 2, 817, 815, 3, 2, 2, 2, 818, 820, 3, 2, 2, 2, 819, 817, 3, 2, 2, 2, 820, 821, 7, 44, 2, 2, 821, 822, 7, 49, 2, 2, 822, 823, 3, 2, 2, 2, 823, 824, 8, 101, 3, 2, 824, 203, 3, 2, 2, 2, 825, 826, 7, 49, 2, 2, 826, 827, 7, 49, 2, 2, 827, 831, 3, 2, 2, 2, 828, 830, 10, 12, 2, 2, 829, 828, 3, 2, 2, 2, 830, 833, 3, 2, 2, 2, 831, 829, 3, 2, 2, 2, 831, 832, 3, 2, 2, 2, 832, 834, 3, 2, 2, 2, 833, 831, 3, 2, 2, 2, 834, 835, 8, 102, 3, 2, 835, 205, 3, 2, 2, 2, 836, 838, 9, 12, 2, 2, 837, 836, 3, 2, 2, 2, 838, 839, 3, 2, 2, 2, 839, 837, 3, 2, 2, 2, 839, 840, 3, 2, 2, 2, 840, 855, 3, 2, 2, 2, 841, 855, 7, 61, 2, 2, 842, 843, 7, 49, 2, 2, 843, 844, 7, 44, 2, 2, 844, 848, 3, 2, 2, 2, 845, 847, 11, 2, 2, 2, 846, 845, 3, 2, 2, 2, 847, 850, 3, 2, 2, 2, 848, 849, 3, 2, 2, 2, 848, 846, 3, 2, 2, 2, 849, 851, 3, 2, 2, 2, 850, 848, 3, 2, 2, 2, 851, 852, 7, 44, 2, 2, 852, 855, 7, 49, 2, 2, 853, 855, 7, 2, 2, 3, 854, 837, 3, 2, 2, 2, 854, 841, 3, 2, 2, 2, 854, 842, 3, 2, 2, 2, 854, 853, 3, 2, 2, 2, 855, 856, 3, 2, 2, 2, 856, 857, 8, 103, 4, 2, 857, 207, 3, 2, 2, 2, 858, 859, 3, 2, 2, 2, 859, 860, 3, 2, 2, 2, 860, 861, 8, 104, 4, 2, 861, 862, 8, 104, 3, 2, 862, 209, 3, 2, 2, 2, 57, 2, 3, 381, 383, 490, 495, 498, 505, 510, 516, 519, 524, 531, 536, 542, 549, 552, 555, 560, 562, 570, 575, 579, 584, 587, 592, 597, 600, 604, 613, 622, 632, 666, 676, 678, 688, 698, 709, 719, 725, 731, 736, 738, 744, 772, 776, 781, 792, 798, 807, 817, 831, 839, 848, 854, 5, 4, 3, 2, 2, 3, 2, 4, 2, 2] \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.java new file mode 100644 index 000000000..2e7528d4e --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.java @@ -0,0 +1,603 @@ +package run.mone.antlr.golang;// Generated from GoLexer.g4 by ANTLR 4.7.1 + +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class GoLexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.7.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + BREAK=1, DEFAULT=2, FUNC=3, INTERFACE=4, SELECT=5, CASE=6, DEFER=7, GO=8, + MAP=9, STRUCT=10, CHAN=11, ELSE=12, GOTO=13, PACKAGE=14, SWITCH=15, CONST=16, + FALLTHROUGH=17, IF=18, RANGE=19, TYPE=20, CONTINUE=21, FOR=22, IMPORT=23, + RETURN=24, VAR=25, NIL_LIT=26, IDENTIFIER=27, L_PAREN=28, R_PAREN=29, + L_CURLY=30, R_CURLY=31, L_BRACKET=32, R_BRACKET=33, ASSIGN=34, COMMA=35, + SEMI=36, COLON=37, DOT=38, PLUS_PLUS=39, MINUS_MINUS=40, DECLARE_ASSIGN=41, + ELLIPSIS=42, LOGICAL_OR=43, LOGICAL_AND=44, EQUALS=45, NOT_EQUALS=46, + LESS=47, LESS_OR_EQUALS=48, GREATER=49, GREATER_OR_EQUALS=50, OR=51, DIV=52, + MOD=53, LSHIFT=54, RSHIFT=55, BIT_CLEAR=56, UNDERLYING=57, EXCLAMATION=58, + PLUS=59, MINUS=60, CARET=61, STAR=62, AMPERSAND=63, RECEIVE=64, DECIMAL_LIT=65, + BINARY_LIT=66, OCTAL_LIT=67, HEX_LIT=68, FLOAT_LIT=69, DECIMAL_FLOAT_LIT=70, + HEX_FLOAT_LIT=71, IMAGINARY_LIT=72, RUNE_LIT=73, BYTE_VALUE=74, OCTAL_BYTE_VALUE=75, + HEX_BYTE_VALUE=76, LITTLE_U_VALUE=77, BIG_U_VALUE=78, RAW_STRING_LIT=79, + INTERPRETED_STRING_LIT=80, WS=81, COMMENT=82, TERMINATOR=83, LINE_COMMENT=84, + NEWLINE=85, WS_NLSEMI=86, COMMENT_NLSEMI=87, LINE_COMMENT_NLSEMI=88, EOS=89, + OTHER=90; + public static final int + NLSEMI=1; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN" + }; + + public static String[] modeNames = { + "DEFAULT_MODE", "NLSEMI" + }; + + public static final String[] ruleNames = { + "BREAK", "DEFAULT", "FUNC", "INTERFACE", "SELECT", "CASE", "DEFER", "GO", + "MAP", "STRUCT", "CHAN", "ELSE", "GOTO", "PACKAGE", "SWITCH", "CONST", + "FALLTHROUGH", "IF", "RANGE", "TYPE", "CONTINUE", "FOR", "IMPORT", "RETURN", + "VAR", "NIL_LIT", "IDENTIFIER", "L_PAREN", "R_PAREN", "L_CURLY", "R_CURLY", + "L_BRACKET", "R_BRACKET", "ASSIGN", "COMMA", "SEMI", "COLON", "DOT", "PLUS_PLUS", + "MINUS_MINUS", "DECLARE_ASSIGN", "ELLIPSIS", "LOGICAL_OR", "LOGICAL_AND", + "EQUALS", "NOT_EQUALS", "LESS", "LESS_OR_EQUALS", "GREATER", "GREATER_OR_EQUALS", + "OR", "DIV", "MOD", "LSHIFT", "RSHIFT", "BIT_CLEAR", "UNDERLYING", "EXCLAMATION", + "PLUS", "MINUS", "CARET", "STAR", "AMPERSAND", "RECEIVE", "DECIMAL_LIT", + "BINARY_LIT", "OCTAL_LIT", "HEX_LIT", "FLOAT_LIT", "DECIMAL_FLOAT_LIT", + "HEX_FLOAT_LIT", "HEX_MANTISSA", "HEX_EXPONENT", "IMAGINARY_LIT", "RUNE", + "RUNE_LIT", "BYTE_VALUE", "OCTAL_BYTE_VALUE", "HEX_BYTE_VALUE", "LITTLE_U_VALUE", + "BIG_U_VALUE", "RAW_STRING_LIT", "INTERPRETED_STRING_LIT", "WS", "COMMENT", + "TERMINATOR", "LINE_COMMENT", "NEWLINE", "UNICODE_VALUE", "ESCAPED_VALUE", + "DECIMALS", "OCTAL_DIGIT", "HEX_DIGIT", "BIN_DIGIT", "EXPONENT", "LETTER", + "UNICODE_DIGIT", "UNICODE_LETTER", "WS_NLSEMI", "COMMENT_NLSEMI", "LINE_COMMENT_NLSEMI", + "EOS", "OTHER" + }; + + private static final String[] _LITERAL_NAMES = { + null, "'break'", "'default'", "'func'", "'interface'", "'select'", "'case'", + "'defer'", "'go'", "'map'", "'struct'", "'chan'", "'else'", "'goto'", + "'package'", "'switch'", "'const'", "'fallthrough'", "'if'", "'range'", + "'type'", "'continue'", "'for'", "'import'", "'return'", "'var'", "'nil'", + null, "'('", "')'", "'{'", "'}'", "'['", "']'", "'='", "','", "';'", "':'", + "'.'", "'++'", "'--'", "':='", "'...'", "'||'", "'&&'", "'=='", "'!='", + "'<'", "'<='", "'>'", "'>='", "'|'", "'/'", "'%'", "'<<'", "'>>'", "'&^'", + "'~'", "'!'", "'+'", "'-'", "'^'", "'*'", "'&'", "'<-'" + }; + private static final String[] _SYMBOLIC_NAMES = { + null, "BREAK", "DEFAULT", "FUNC", "INTERFACE", "SELECT", "CASE", "DEFER", + "GO", "MAP", "STRUCT", "CHAN", "ELSE", "GOTO", "PACKAGE", "SWITCH", "CONST", + "FALLTHROUGH", "IF", "RANGE", "TYPE", "CONTINUE", "FOR", "IMPORT", "RETURN", + "VAR", "NIL_LIT", "IDENTIFIER", "L_PAREN", "R_PAREN", "L_CURLY", "R_CURLY", + "L_BRACKET", "R_BRACKET", "ASSIGN", "COMMA", "SEMI", "COLON", "DOT", "PLUS_PLUS", + "MINUS_MINUS", "DECLARE_ASSIGN", "ELLIPSIS", "LOGICAL_OR", "LOGICAL_AND", + "EQUALS", "NOT_EQUALS", "LESS", "LESS_OR_EQUALS", "GREATER", "GREATER_OR_EQUALS", + "OR", "DIV", "MOD", "LSHIFT", "RSHIFT", "BIT_CLEAR", "UNDERLYING", "EXCLAMATION", + "PLUS", "MINUS", "CARET", "STAR", "AMPERSAND", "RECEIVE", "DECIMAL_LIT", + "BINARY_LIT", "OCTAL_LIT", "HEX_LIT", "FLOAT_LIT", "DECIMAL_FLOAT_LIT", + "HEX_FLOAT_LIT", "IMAGINARY_LIT", "RUNE_LIT", "BYTE_VALUE", "OCTAL_BYTE_VALUE", + "HEX_BYTE_VALUE", "LITTLE_U_VALUE", "BIG_U_VALUE", "RAW_STRING_LIT", "INTERPRETED_STRING_LIT", + "WS", "COMMENT", "TERMINATOR", "LINE_COMMENT", "NEWLINE", "WS_NLSEMI", + "COMMENT_NLSEMI", "LINE_COMMENT_NLSEMI", "EOS", "OTHER" + }; + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public GoLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "GoLexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\\\u035f\b\1\b\1\4"+ + "\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n"+ + "\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ + "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+ + "\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t"+ + " \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t"+ + "+\4,\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64"+ + "\t\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t"+ + "=\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4"+ + "I\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\t"+ + "T\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_"+ + "\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\3\2\3\2\3\2\3\2"+ + "\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3"+ + "\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7"+ + "\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3"+ + "\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r"+ + "\3\r\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17"+ + "\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22"+ + "\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\23"+ + "\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\26"+ + "\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3\27"+ + "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31"+ + "\3\31\3\31\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34"+ + "\3\34\7\34\u017e\n\34\f\34\16\34\u0181\13\34\3\34\3\34\3\35\3\35\3\36"+ + "\3\36\3\36\3\36\3\37\3\37\3 \3 \3 \3 \3!\3!\3\"\3\"\3\"\3\"\3#\3#\3$\3"+ + "$\3%\3%\3&\3&\3\'\3\'\3(\3(\3(\3(\3(\3)\3)\3)\3)\3)\3*\3*\3*\3+\3+\3+"+ + "\3+\3,\3,\3,\3-\3-\3-\3.\3.\3.\3/\3/\3/\3\60\3\60\3\61\3\61\3\61\3\62"+ + "\3\62\3\63\3\63\3\63\3\64\3\64\3\65\3\65\3\66\3\66\3\67\3\67\3\67\38\3"+ + "8\38\39\39\39\3:\3:\3;\3;\3<\3<\3=\3=\3>\3>\3?\3?\3@\3@\3A\3A\3A\3B\3"+ + "B\3B\5B\u01eb\nB\3B\7B\u01ee\nB\fB\16B\u01f1\13B\5B\u01f3\nB\3B\3B\3C"+ + "\3C\3C\5C\u01fa\nC\3C\6C\u01fd\nC\rC\16C\u01fe\3C\3C\3D\3D\5D\u0205\n"+ + "D\3D\5D\u0208\nD\3D\6D\u020b\nD\rD\16D\u020c\3D\3D\3E\3E\3E\5E\u0214\n"+ + "E\3E\6E\u0217\nE\rE\16E\u0218\3E\3E\3F\3F\5F\u021f\nF\3F\3F\3G\3G\3G\5"+ + "G\u0226\nG\3G\5G\u0229\nG\3G\5G\u022c\nG\3G\3G\3G\5G\u0231\nG\5G\u0233"+ + "\nG\3H\3H\3H\3H\3H\3I\5I\u023b\nI\3I\6I\u023e\nI\rI\16I\u023f\3I\3I\5"+ + "I\u0244\nI\3I\7I\u0247\nI\fI\16I\u024a\13I\5I\u024c\nI\3I\3I\3I\5I\u0251"+ + "\nI\3I\7I\u0254\nI\fI\16I\u0257\13I\5I\u0259\nI\3J\3J\5J\u025d\nJ\3J\3"+ + "J\3K\3K\3K\3K\3K\5K\u0266\nK\3K\3K\3K\3K\3L\3L\3L\5L\u026f\nL\3L\3L\3"+ + "M\3M\3M\3M\3N\3N\5N\u0279\nN\3O\3O\3O\3O\3O\3P\3P\3P\3P\3P\3Q\3Q\3Q\3"+ + "Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3S\3S\7S\u0299\nS\fS\16S\u029c"+ + "\13S\3S\3S\3S\3S\3T\3T\3T\7T\u02a5\nT\fT\16T\u02a8\13T\3T\3T\3T\3T\3U"+ + "\6U\u02af\nU\rU\16U\u02b0\3U\3U\3V\3V\3V\3V\7V\u02b9\nV\fV\16V\u02bc\13"+ + "V\3V\3V\3V\3V\3V\3W\6W\u02c4\nW\rW\16W\u02c5\3W\3W\3X\3X\3X\3X\7X\u02ce"+ + "\nX\fX\16X\u02d1\13X\3X\3X\3Y\5Y\u02d6\nY\3Y\3Y\6Y\u02da\nY\rY\16Y\u02db"+ + "\3Y\6Y\u02df\nY\rY\16Y\u02e0\5Y\u02e3\nY\3Z\3Z\3Z\3Z\5Z\u02e9\nZ\3[\3"+ + "[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3[\3"+ + "[\3[\5[\u0305\n[\3\\\3\\\5\\\u0309\n\\\3\\\7\\\u030c\n\\\f\\\16\\\u030f"+ + "\13\\\3]\3]\3^\3^\3_\3_\3`\3`\5`\u0319\n`\3`\3`\3a\3a\5a\u031f\na\3b\3"+ + "b\3c\3c\3d\6d\u0326\nd\rd\16d\u0327\3d\3d\3e\3e\3e\3e\7e\u0330\ne\fe\16"+ + "e\u0333\13e\3e\3e\3e\3e\3e\3f\3f\3f\3f\7f\u033e\nf\ff\16f\u0341\13f\3"+ + "f\3f\3g\6g\u0346\ng\rg\16g\u0347\3g\3g\3g\3g\3g\7g\u034f\ng\fg\16g\u0352"+ + "\13g\3g\3g\3g\5g\u0357\ng\3g\3g\3h\3h\3h\3h\3h\5\u02ba\u0331\u0350\2i"+ + "\4\3\6\4\b\5\n\6\f\7\16\b\20\t\22\n\24\13\26\f\30\r\32\16\34\17\36\20"+ + " \21\"\22$\23&\24(\25*\26,\27.\30\60\31\62\32\64\33\66\348\35:\36<\37"+ + "> @!B\"D#F$H%J&L\'N(P)R*T+V,X-Z.\\/^\60`\61b\62d\63f\64h\65j\66l\67n8"+ + "p9r:t;v|?~@\u0080A\u0082B\u0084C\u0086D\u0088E\u008aF\u008cG\u008e"+ + "H\u0090I\u0092\2\u0094\2\u0096J\u0098\2\u009aK\u009cL\u009eM\u00a0N\u00a2"+ + "O\u00a4P\u00a6Q\u00a8R\u00aaS\u00acT\u00aeU\u00b0V\u00b2W\u00b4\2\u00b6"+ + "\2\u00b8\2\u00ba\2\u00bc\2\u00be\2\u00c0\2\u00c2\2\u00c4\2\u00c6\2\u00c8"+ + "X\u00caY\u00ccZ\u00ce[\u00d0\\\4\2\3\23\3\2\63;\3\2\62;\4\2DDdd\4\2QQ"+ + "qq\4\2ZZzz\4\2RRrr\4\2--//\3\2bb\4\2$$^^\4\2\13\13\"\"\4\2\f\f\17\17\5"+ + "\2\f\f\17\17))\13\2$$))^^cdhhppttvvxx\3\2\629\5\2\62;CHch\3\2\62\63\4"+ + "\2GGgg\48\2\62\2;\2\u0662\2\u066b\2\u06f2\2\u06fb\2\u07c2\2\u07cb\2\u0968"+ + "\2\u0971\2\u09e8\2\u09f1\2\u0a68\2\u0a71\2\u0ae8\2\u0af1\2\u0b68\2\u0b71"+ + "\2\u0be8\2\u0bf1\2\u0c68\2\u0c71\2\u0ce8\2\u0cf1\2\u0d68\2\u0d71\2\u0de8"+ + "\2\u0df1\2\u0e52\2\u0e5b\2\u0ed2\2\u0edb\2\u0f22\2\u0f2b\2\u1042\2\u104b"+ + "\2\u1092\2\u109b\2\u17e2\2\u17eb\2\u1812\2\u181b\2\u1948\2\u1951\2\u19d2"+ + "\2\u19db\2\u1a82\2\u1a8b\2\u1a92\2\u1a9b\2\u1b52\2\u1b5b\2\u1bb2\2\u1bbb"+ + "\2\u1c42\2\u1c4b\2\u1c52\2\u1c5b\2\ua622\2\ua62b\2\ua8d2\2\ua8db\2\ua902"+ + "\2\ua90b\2\ua9d2\2\ua9db\2\ua9f2\2\ua9fb\2\uaa52\2\uaa5b\2\uabf2\2\uabfb"+ + "\2\uff12\2\uff1b\2\u04a2\3\u04ab\3\u1068\3\u1071\3\u10f2\3\u10fb\3\u1138"+ + "\3\u1141\3\u11d2\3\u11db\3\u12f2\3\u12fb\3\u1452\3\u145b\3\u14d2\3\u14db"+ + "\3\u1652\3\u165b\3\u16c2\3\u16cb\3\u1732\3\u173b\3\u18e2\3\u18eb\3\u1c52"+ + "\3\u1c5b\3\u6a62\3\u6a6b\3\u6b52\3\u6b5b\3\ud7d0\3\ud801\3\ue952\3\ue95b"+ + "\3\u023d\2C\2\\\2c\2|\2\u00ac\2\u00ac\2\u00b7\2\u00b7\2\u00bc\2\u00bc"+ + "\2\u00c2\2\u00d8\2\u00da\2\u00f8\2\u00fa\2\u02c3\2\u02c8\2\u02d3\2\u02e2"+ + "\2\u02e6\2\u02ee\2\u02ee\2\u02f0\2\u02f0\2\u0372\2\u0376\2\u0378\2\u0379"+ + "\2\u037c\2\u037f\2\u0381\2\u0381\2\u0388\2\u0388\2\u038a\2\u038c\2\u038e"+ + "\2\u038e\2\u0390\2\u03a3\2\u03a5\2\u03f7\2\u03f9\2\u0483\2\u048c\2\u0531"+ + "\2\u0533\2\u0558\2\u055b\2\u055b\2\u0563\2\u0589\2\u05d2\2\u05ec\2\u05f2"+ + "\2\u05f4\2\u0622\2\u064c\2\u0670\2\u0671\2\u0673\2\u06d5\2\u06d7\2\u06d7"+ + "\2\u06e7\2\u06e8\2\u06f0\2\u06f1\2\u06fc\2\u06fe\2\u0701\2\u0701\2\u0712"+ + "\2\u0712\2\u0714\2\u0731\2\u074f\2\u07a7\2\u07b3\2\u07b3\2\u07cc\2\u07ec"+ + "\2\u07f6\2\u07f7\2\u07fc\2\u07fc\2\u0802\2\u0817\2\u081c\2\u081c\2\u0826"+ + "\2\u0826\2\u082a\2\u082a\2\u0842\2\u085a\2\u08a2\2\u08b6\2\u08b8\2\u08bf"+ + "\2\u0906\2\u093b\2\u093f\2\u093f\2\u0952\2\u0952\2\u095a\2\u0963\2\u0973"+ + "\2\u0982\2\u0987\2\u098e\2\u0991\2\u0992\2\u0995\2\u09aa\2\u09ac\2\u09b2"+ + "\2\u09b4\2\u09b4\2\u09b8\2\u09bb\2\u09bf\2\u09bf\2\u09d0\2\u09d0\2\u09de"+ + "\2\u09df\2\u09e1\2\u09e3\2\u09f2\2\u09f3\2\u0a07\2\u0a0c\2\u0a11\2\u0a12"+ + "\2\u0a15\2\u0a2a\2\u0a2c\2\u0a32\2\u0a34\2\u0a35\2\u0a37\2\u0a38\2\u0a3a"+ + "\2\u0a3b\2\u0a5b\2\u0a5e\2\u0a60\2\u0a60\2\u0a74\2\u0a76\2\u0a87\2\u0a8f"+ + "\2\u0a91\2\u0a93\2\u0a95\2\u0aaa\2\u0aac\2\u0ab2\2\u0ab4\2\u0ab5\2\u0ab7"+ + "\2\u0abb\2\u0abf\2\u0abf\2\u0ad2\2\u0ad2\2\u0ae2\2\u0ae3\2\u0afb\2\u0afb"+ + "\2\u0b07\2\u0b0e\2\u0b11\2\u0b12\2\u0b15\2\u0b2a\2\u0b2c\2\u0b32\2\u0b34"+ + "\2\u0b35\2\u0b37\2\u0b3b\2\u0b3f\2\u0b3f\2\u0b5e\2\u0b5f\2\u0b61\2\u0b63"+ + "\2\u0b73\2\u0b73\2\u0b85\2\u0b85\2\u0b87\2\u0b8c\2\u0b90\2\u0b92\2\u0b94"+ + "\2\u0b97\2\u0b9b\2\u0b9c\2\u0b9e\2\u0b9e\2\u0ba0\2\u0ba1\2\u0ba5\2\u0ba6"+ + "\2\u0baa\2\u0bac\2\u0bb0\2\u0bbb\2\u0bd2\2\u0bd2\2\u0c07\2\u0c0e\2\u0c10"+ + "\2\u0c12\2\u0c14\2\u0c2a\2\u0c2c\2\u0c3b\2\u0c3f\2\u0c3f\2\u0c5a\2\u0c5c"+ + "\2\u0c62\2\u0c63\2\u0c82\2\u0c82\2\u0c87\2\u0c8e\2\u0c90\2\u0c92\2\u0c94"+ + "\2\u0caa\2\u0cac\2\u0cb5\2\u0cb7\2\u0cbb\2\u0cbf\2\u0cbf\2\u0ce0\2\u0ce0"+ + "\2\u0ce2\2\u0ce3\2\u0cf3\2\u0cf4\2\u0d07\2\u0d0e\2\u0d10\2\u0d12\2\u0d14"+ + "\2\u0d3c\2\u0d3f\2\u0d3f\2\u0d50\2\u0d50\2\u0d56\2\u0d58\2\u0d61\2\u0d63"+ + "\2\u0d7c\2\u0d81\2\u0d87\2\u0d98\2\u0d9c\2\u0db3\2\u0db5\2\u0dbd\2\u0dbf"+ + "\2\u0dbf\2\u0dc2\2\u0dc8\2\u0e03\2\u0e32\2\u0e34\2\u0e35\2\u0e42\2\u0e48"+ + "\2\u0e83\2\u0e84\2\u0e86\2\u0e86\2\u0e89\2\u0e8a\2\u0e8c\2\u0e8c\2\u0e8f"+ + "\2\u0e8f\2\u0e96\2\u0e99\2\u0e9b\2\u0ea1\2\u0ea3\2\u0ea5\2\u0ea7\2\u0ea7"+ + "\2\u0ea9\2\u0ea9\2\u0eac\2\u0ead\2\u0eaf\2\u0eb2\2\u0eb4\2\u0eb5\2\u0ebf"+ + "\2\u0ebf\2\u0ec2\2\u0ec6\2\u0ec8\2\u0ec8\2\u0ede\2\u0ee1\2\u0f02\2\u0f02"+ + "\2\u0f42\2\u0f49\2\u0f4b\2\u0f6e\2\u0f8a\2\u0f8e\2\u1002\2\u102c\2\u1041"+ + "\2\u1041\2\u1052\2\u1057\2\u105c\2\u105f\2\u1063\2\u1063\2\u1067\2\u1068"+ + "\2\u1070\2\u1072\2\u1077\2\u1083\2\u1090\2\u1090\2\u10a2\2\u10c7\2\u10c9"+ + "\2\u10c9\2\u10cf\2\u10cf\2\u10d2\2\u10fc\2\u10fe\2\u124a\2\u124c\2\u124f"+ + "\2\u1252\2\u1258\2\u125a\2\u125a\2\u125c\2\u125f\2\u1262\2\u128a\2\u128c"+ + "\2\u128f\2\u1292\2\u12b2\2\u12b4\2\u12b7\2\u12ba\2\u12c0\2\u12c2\2\u12c2"+ + "\2\u12c4\2\u12c7\2\u12ca\2\u12d8\2\u12da\2\u1312\2\u1314\2\u1317\2\u131a"+ + "\2\u135c\2\u1382\2\u1391\2\u13a2\2\u13f7\2\u13fa\2\u13ff\2\u1403\2\u166e"+ + "\2\u1671\2\u1681\2\u1683\2\u169c\2\u16a2\2\u16ec\2\u16f3\2\u16fa\2\u1702"+ + "\2\u170e\2\u1710\2\u1713\2\u1722\2\u1733\2\u1742\2\u1753\2\u1762\2\u176e"+ + "\2\u1770\2\u1772\2\u1782\2\u17b5\2\u17d9\2\u17d9\2\u17de\2\u17de\2\u1822"+ + "\2\u1879\2\u1882\2\u1886\2\u1889\2\u18aa\2\u18ac\2\u18ac\2\u18b2\2\u18f7"+ + "\2\u1902\2\u1920\2\u1952\2\u196f\2\u1972\2\u1976\2\u1982\2\u19ad\2\u19b2"+ + "\2\u19cb\2\u1a02\2\u1a18\2\u1a22\2\u1a56\2\u1aa9\2\u1aa9\2\u1b07\2\u1b35"+ + "\2\u1b47\2\u1b4d\2\u1b85\2\u1ba2\2\u1bb0\2\u1bb1\2\u1bbc\2\u1be7\2\u1c02"+ + "\2\u1c25\2\u1c4f\2\u1c51\2\u1c5c\2\u1c7f\2\u1c82\2\u1c8a\2\u1ceb\2\u1cee"+ + "\2\u1cf0\2\u1cf3\2\u1cf7\2\u1cf8\2\u1d02\2\u1dc1\2\u1e02\2\u1f17\2\u1f1a"+ + "\2\u1f1f\2\u1f22\2\u1f47\2\u1f4a\2\u1f4f\2\u1f52\2\u1f59\2\u1f5b\2\u1f5b"+ + "\2\u1f5d\2\u1f5d\2\u1f5f\2\u1f5f\2\u1f61\2\u1f7f\2\u1f82\2\u1fb6\2\u1fb8"+ + "\2\u1fbe\2\u1fc0\2\u1fc0\2\u1fc4\2\u1fc6\2\u1fc8\2\u1fce\2\u1fd2\2\u1fd5"+ + "\2\u1fd8\2\u1fdd\2\u1fe2\2\u1fee\2\u1ff4\2\u1ff6\2\u1ff8\2\u1ffe\2\u2073"+ + "\2\u2073\2\u2081\2\u2081\2\u2092\2\u209e\2\u2104\2\u2104\2\u2109\2\u2109"+ + "\2\u210c\2\u2115\2\u2117\2\u2117\2\u211b\2\u211f\2\u2126\2\u2126\2\u2128"+ + "\2\u2128\2\u212a\2\u212a\2\u212c\2\u212f\2\u2131\2\u213b\2\u213e\2\u2141"+ + "\2\u2147\2\u214b\2\u2150\2\u2150\2\u2185\2\u2186\2\u2c02\2\u2c30\2\u2c32"+ + "\2\u2c60\2\u2c62\2\u2ce6\2\u2ced\2\u2cf0\2\u2cf4\2\u2cf5\2\u2d02\2\u2d27"+ + "\2\u2d29\2\u2d29\2\u2d2f\2\u2d2f\2\u2d32\2\u2d69\2\u2d71\2\u2d71\2\u2d82"+ + "\2\u2d98\2\u2da2\2\u2da8\2\u2daa\2\u2db0\2\u2db2\2\u2db8\2\u2dba\2\u2dc0"+ + "\2\u2dc2\2\u2dc8\2\u2dca\2\u2dd0\2\u2dd2\2\u2dd8\2\u2dda\2\u2de0\2\u2e31"+ + "\2\u2e31\2\u3007\2\u3008\2\u3033\2\u3037\2\u303d\2\u303e\2\u3043\2\u3098"+ + "\2\u309f\2\u30a1\2\u30a3\2\u30fc\2\u30fe\2\u3101\2\u3107\2\u312f\2\u3133"+ + "\2\u3190\2\u31a2\2\u31bc\2\u31f2\2\u3201\2\u3402\2\u4db7\2\u4e02\2\u9fd7"+ + "\2\ua002\2\ua48e\2\ua4d2\2\ua4ff\2\ua502\2\ua60e\2\ua612\2\ua621\2\ua62c"+ + "\2\ua62d\2\ua642\2\ua670\2\ua681\2\ua69f\2\ua6a2\2\ua6e7\2\ua719\2\ua721"+ + "\2\ua724\2\ua78a\2\ua78d\2\ua7b0\2\ua7b2\2\ua7b9\2\ua7f9\2\ua803\2\ua805"+ + "\2\ua807\2\ua809\2\ua80c\2\ua80e\2\ua824\2\ua842\2\ua875\2\ua884\2\ua8b5"+ + "\2\ua8f4\2\ua8f9\2\ua8fd\2\ua8fd\2\ua8ff\2\ua8ff\2\ua90c\2\ua927\2\ua932"+ + "\2\ua948\2\ua962\2\ua97e\2\ua986\2\ua9b4\2\ua9d1\2\ua9d1\2\ua9e2\2\ua9e6"+ + "\2\ua9e8\2\ua9f1\2\ua9fc\2\uaa00\2\uaa02\2\uaa2a\2\uaa42\2\uaa44\2\uaa46"+ + "\2\uaa4d\2\uaa62\2\uaa78\2\uaa7c\2\uaa7c\2\uaa80\2\uaab1\2\uaab3\2\uaab3"+ + "\2\uaab7\2\uaab8\2\uaabb\2\uaabf\2\uaac2\2\uaac2\2\uaac4\2\uaac4\2\uaadd"+ + "\2\uaadf\2\uaae2\2\uaaec\2\uaaf4\2\uaaf6\2\uab03\2\uab08\2\uab0b\2\uab10"+ + "\2\uab13\2\uab18\2\uab22\2\uab28\2\uab2a\2\uab30\2\uab32\2\uab5c\2\uab5e"+ + "\2\uab67\2\uab72\2\uabe4\2\uac02\2\ud7a5\2\ud7b2\2\ud7c8\2\ud7cd\2\ud7fd"+ + "\2\uf902\2\ufa6f\2\ufa72\2\ufadb\2\ufb02\2\ufb08\2\ufb15\2\ufb19\2\ufb1f"+ + "\2\ufb1f\2\ufb21\2\ufb2a\2\ufb2c\2\ufb38\2\ufb3a\2\ufb3e\2\ufb40\2\ufb40"+ + "\2\ufb42\2\ufb43\2\ufb45\2\ufb46\2\ufb48\2\ufbb3\2\ufbd5\2\ufd3f\2\ufd52"+ + "\2\ufd91\2\ufd94\2\ufdc9\2\ufdf2\2\ufdfd\2\ufe72\2\ufe76\2\ufe78\2\ufefe"+ + "\2\uff23\2\uff3c\2\uff43\2\uff5c\2\uff68\2\uffc0\2\uffc4\2\uffc9\2\uffcc"+ + "\2\uffd1\2\uffd4\2\uffd9\2\uffdc\2\uffde\2\2\3\r\3\17\3(\3*\3<\3>\3?\3"+ + "A\3O\3R\3_\3\u0082\3\u00fc\3\u0282\3\u029e\3\u02a2\3\u02d2\3\u0302\3\u0321"+ + "\3\u0332\3\u0342\3\u0344\3\u034b\3\u0352\3\u0377\3\u0382\3\u039f\3\u03a2"+ + "\3\u03c5\3\u03ca\3\u03d1\3\u0402\3\u049f\3\u04b2\3\u04d5\3\u04da\3\u04fd"+ + "\3\u0502\3\u0529\3\u0532\3\u0565\3\u0602\3\u0738\3\u0742\3\u0757\3\u0762"+ + "\3\u0769\3\u0802\3\u0807\3\u080a\3\u080a\3\u080c\3\u0837\3\u0839\3\u083a"+ + "\3\u083e\3\u083e\3\u0841\3\u0857\3\u0862\3\u0878\3\u0882\3\u08a0\3\u08e2"+ + "\3\u08f4\3\u08f6\3\u08f7\3\u0902\3\u0917\3\u0922\3\u093b\3\u0982\3\u09b9"+ + "\3\u09c0\3\u09c1\3\u0a02\3\u0a02\3\u0a12\3\u0a15\3\u0a17\3\u0a19\3\u0a1b"+ + "\3\u0a35\3\u0a62\3\u0a7e\3\u0a82\3\u0a9e\3\u0ac2\3\u0ac9\3\u0acb\3\u0ae6"+ + "\3\u0b02\3\u0b37\3\u0b42\3\u0b57\3\u0b62\3\u0b74\3\u0b82\3\u0b93\3\u0c02"+ + "\3\u0c4a\3\u0c82\3\u0cb4\3\u0cc2\3\u0cf4\3\u1005\3\u1039\3\u1085\3\u10b1"+ + "\3\u10d2\3\u10ea\3\u1105\3\u1128\3\u1152\3\u1174\3\u1178\3\u1178\3\u1185"+ + "\3\u11b4\3\u11c3\3\u11c6\3\u11dc\3\u11dc\3\u11de\3\u11de\3\u1202\3\u1213"+ + "\3\u1215\3\u122d\3\u1282\3\u1288\3\u128a\3\u128a\3\u128c\3\u128f\3\u1291"+ + "\3\u129f\3\u12a1\3\u12aa\3\u12b2\3\u12e0\3\u1307\3\u130e\3\u1311\3\u1312"+ + "\3\u1315\3\u132a\3\u132c\3\u1332\3\u1334\3\u1335\3\u1337\3\u133b\3\u133f"+ + "\3\u133f\3\u1352\3\u1352\3\u135f\3\u1363\3\u1402\3\u1436\3\u1449\3\u144c"+ + "\3\u1482\3\u14b1\3\u14c6\3\u14c7\3\u14c9\3\u14c9\3\u1582\3\u15b0\3\u15da"+ + "\3\u15dd\3\u1602\3\u1631\3\u1646\3\u1646\3\u1682\3\u16ac\3\u1702\3\u171b"+ + "\3\u18a2\3\u18e1\3\u1901\3\u1901\3\u1ac2\3\u1afa\3\u1c02\3\u1c0a\3\u1c0c"+ + "\3\u1c30\3\u1c42\3\u1c42\3\u1c74\3\u1c91\3\u2002\3\u239b\3\u2482\3\u2545"+ + "\3\u3002\3\u3430\3\u4402\3\u4648\3\u6802\3\u6a3a\3\u6a42\3\u6a60\3\u6ad2"+ + "\3\u6aef\3\u6b02\3\u6b31\3\u6b42\3\u6b45\3\u6b65\3\u6b79\3\u6b7f\3\u6b91"+ + "\3\u6f02\3\u6f46\3\u6f52\3\u6f52\3\u6f95\3\u6fa1\3\u6fe2\3\u6fe2\3\u7002"+ + "\3\u87ee\3\u8802\3\u8af4\3\ub002\3\ub003\3\ubc02\3\ubc6c\3\ubc72\3\ubc7e"+ + "\3\ubc82\3\ubc8a\3\ubc92\3\ubc9b\3\ud402\3\ud456\3\ud458\3\ud49e\3\ud4a0"+ + "\3\ud4a1\3\ud4a4\3\ud4a4\3\ud4a7\3\ud4a8\3\ud4ab\3\ud4ae\3\ud4b0\3\ud4bb"+ + "\3\ud4bd\3\ud4bd\3\ud4bf\3\ud4c5\3\ud4c7\3\ud507\3\ud509\3\ud50c\3\ud50f"+ + "\3\ud516\3\ud518\3\ud51e\3\ud520\3\ud53b\3\ud53d\3\ud540\3\ud542\3\ud546"+ + "\3\ud548\3\ud548\3\ud54c\3\ud552\3\ud554\3\ud6a7\3\ud6aa\3\ud6c2\3\ud6c4"+ + "\3\ud6dc\3\ud6de\3\ud6fc\3\ud6fe\3\ud716\3\ud718\3\ud736\3\ud738\3\ud750"+ + "\3\ud752\3\ud770\3\ud772\3\ud78a\3\ud78c\3\ud7aa\3\ud7ac\3\ud7c4\3\ud7c6"+ + "\3\ud7cd\3\ue802\3\ue8c6\3\ue902\3\ue945\3\uee02\3\uee05\3\uee07\3\uee21"+ + "\3\uee23\3\uee24\3\uee26\3\uee26\3\uee29\3\uee29\3\uee2b\3\uee34\3\uee36"+ + "\3\uee39\3\uee3b\3\uee3b\3\uee3d\3\uee3d\3\uee44\3\uee44\3\uee49\3\uee49"+ + "\3\uee4b\3\uee4b\3\uee4d\3\uee4d\3\uee4f\3\uee51\3\uee53\3\uee54\3\uee56"+ + "\3\uee56\3\uee59\3\uee59\3\uee5b\3\uee5b\3\uee5d\3\uee5d\3\uee5f\3\uee5f"+ + "\3\uee61\3\uee61\3\uee63\3\uee64\3\uee66\3\uee66\3\uee69\3\uee6c\3\uee6e"+ + "\3\uee74\3\uee76\3\uee79\3\uee7b\3\uee7e\3\uee80\3\uee80\3\uee82\3\uee8b"+ + "\3\uee8d\3\uee9d\3\ueea3\3\ueea5\3\ueea7\3\ueeab\3\ueead\3\ueebd\3\2\4"+ + "\ua6d8\4\ua702\4\ub736\4\ub742\4\ub81f\4\ub822\4\ucea3\4\uf802\4\ufa1f"+ + "\4\u0390\2\4\3\2\2\2\2\6\3\2\2\2\2\b\3\2\2\2\2\n\3\2\2\2\2\f\3\2\2\2\2"+ + "\16\3\2\2\2\2\20\3\2\2\2\2\22\3\2\2\2\2\24\3\2\2\2\2\26\3\2\2\2\2\30\3"+ + "\2\2\2\2\32\3\2\2\2\2\34\3\2\2\2\2\36\3\2\2\2\2 \3\2\2\2\2\"\3\2\2\2\2"+ + "$\3\2\2\2\2&\3\2\2\2\2(\3\2\2\2\2*\3\2\2\2\2,\3\2\2\2\2.\3\2\2\2\2\60"+ + "\3\2\2\2\2\62\3\2\2\2\2\64\3\2\2\2\2\66\3\2\2\2\28\3\2\2\2\2:\3\2\2\2"+ + "\2<\3\2\2\2\2>\3\2\2\2\2@\3\2\2\2\2B\3\2\2\2\2D\3\2\2\2\2F\3\2\2\2\2H"+ + "\3\2\2\2\2J\3\2\2\2\2L\3\2\2\2\2N\3\2\2\2\2P\3\2\2\2\2R\3\2\2\2\2T\3\2"+ + "\2\2\2V\3\2\2\2\2X\3\2\2\2\2Z\3\2\2\2\2\\\3\2\2\2\2^\3\2\2\2\2`\3\2\2"+ + "\2\2b\3\2\2\2\2d\3\2\2\2\2f\3\2\2\2\2h\3\2\2\2\2j\3\2\2\2\2l\3\2\2\2\2"+ + "n\3\2\2\2\2p\3\2\2\2\2r\3\2\2\2\2t\3\2\2\2\2v\3\2\2\2\2x\3\2\2\2\2z\3"+ + "\2\2\2\2|\3\2\2\2\2~\3\2\2\2\2\u0080\3\2\2\2\2\u0082\3\2\2\2\2\u0084\3"+ + "\2\2\2\2\u0086\3\2\2\2\2\u0088\3\2\2\2\2\u008a\3\2\2\2\2\u008c\3\2\2\2"+ + "\2\u008e\3\2\2\2\2\u0090\3\2\2\2\2\u0096\3\2\2\2\2\u009a\3\2\2\2\2\u009c"+ + "\3\2\2\2\2\u009e\3\2\2\2\2\u00a0\3\2\2\2\2\u00a2\3\2\2\2\2\u00a4\3\2\2"+ + "\2\2\u00a6\3\2\2\2\2\u00a8\3\2\2\2\2\u00aa\3\2\2\2\2\u00ac\3\2\2\2\2\u00ae"+ + "\3\2\2\2\2\u00b0\3\2\2\2\2\u00b2\3\2\2\2\3\u00c8\3\2\2\2\3\u00ca\3\2\2"+ + "\2\3\u00cc\3\2\2\2\3\u00ce\3\2\2\2\3\u00d0\3\2\2\2\4\u00d2\3\2\2\2\6\u00da"+ + "\3\2\2\2\b\u00e2\3\2\2\2\n\u00e7\3\2\2\2\f\u00f1\3\2\2\2\16\u00f8\3\2"+ + "\2\2\20\u00fd\3\2\2\2\22\u0103\3\2\2\2\24\u0106\3\2\2\2\26\u010a\3\2\2"+ + "\2\30\u0111\3\2\2\2\32\u0116\3\2\2\2\34\u011b\3\2\2\2\36\u0120\3\2\2\2"+ + " \u0128\3\2\2\2\"\u012f\3\2\2\2$\u0135\3\2\2\2&\u0143\3\2\2\2(\u0146\3"+ + "\2\2\2*\u014c\3\2\2\2,\u0151\3\2\2\2.\u015c\3\2\2\2\60\u0160\3\2\2\2\62"+ + "\u0167\3\2\2\2\64\u0170\3\2\2\2\66\u0174\3\2\2\28\u017a\3\2\2\2:\u0184"+ + "\3\2\2\2<\u0186\3\2\2\2>\u018a\3\2\2\2@\u018c\3\2\2\2B\u0190\3\2\2\2D"+ + "\u0192\3\2\2\2F\u0196\3\2\2\2H\u0198\3\2\2\2J\u019a\3\2\2\2L\u019c\3\2"+ + "\2\2N\u019e\3\2\2\2P\u01a0\3\2\2\2R\u01a5\3\2\2\2T\u01aa\3\2\2\2V\u01ad"+ + "\3\2\2\2X\u01b1\3\2\2\2Z\u01b4\3\2\2\2\\\u01b7\3\2\2\2^\u01ba\3\2\2\2"+ + "`\u01bd\3\2\2\2b\u01bf\3\2\2\2d\u01c2\3\2\2\2f\u01c4\3\2\2\2h\u01c7\3"+ + "\2\2\2j\u01c9\3\2\2\2l\u01cb\3\2\2\2n\u01cd\3\2\2\2p\u01d0\3\2\2\2r\u01d3"+ + "\3\2\2\2t\u01d6\3\2\2\2v\u01d8\3\2\2\2x\u01da\3\2\2\2z\u01dc\3\2\2\2|"+ + "\u01de\3\2\2\2~\u01e0\3\2\2\2\u0080\u01e2\3\2\2\2\u0082\u01e4\3\2\2\2"+ + "\u0084\u01f2\3\2\2\2\u0086\u01f6\3\2\2\2\u0088\u0202\3\2\2\2\u008a\u0210"+ + "\3\2\2\2\u008c\u021e\3\2\2\2\u008e\u0232\3\2\2\2\u0090\u0234\3\2\2\2\u0092"+ + "\u0258\3\2\2\2\u0094\u025a\3\2\2\2\u0096\u0265\3\2\2\2\u0098\u026b\3\2"+ + "\2\2\u009a\u0272\3\2\2\2\u009c\u0278\3\2\2\2\u009e\u027a\3\2\2\2\u00a0"+ + "\u027f\3\2\2\2\u00a2\u0284\3\2\2\2\u00a4\u028b\3\2\2\2\u00a6\u0296\3\2"+ + "\2\2\u00a8\u02a1\3\2\2\2\u00aa\u02ae\3\2\2\2\u00ac\u02b4\3\2\2\2\u00ae"+ + "\u02c3\3\2\2\2\u00b0\u02c9\3\2\2\2\u00b2\u02e2\3\2\2\2\u00b4\u02e8\3\2"+ + "\2\2\u00b6\u02ea\3\2\2\2\u00b8\u0306\3\2\2\2\u00ba\u0310\3\2\2\2\u00bc"+ + "\u0312\3\2\2\2\u00be\u0314\3\2\2\2\u00c0\u0316\3\2\2\2\u00c2\u031e\3\2"+ + "\2\2\u00c4\u0320\3\2\2\2\u00c6\u0322\3\2\2\2\u00c8\u0325\3\2\2\2\u00ca"+ + "\u032b\3\2\2\2\u00cc\u0339\3\2\2\2\u00ce\u0356\3\2\2\2\u00d0\u035a\3\2"+ + "\2\2\u00d2\u00d3\7d\2\2\u00d3\u00d4\7t\2\2\u00d4\u00d5\7g\2\2\u00d5\u00d6"+ + "\7c\2\2\u00d6\u00d7\7m\2\2\u00d7\u00d8\3\2\2\2\u00d8\u00d9\b\2\2\2\u00d9"+ + "\5\3\2\2\2\u00da\u00db\7f\2\2\u00db\u00dc\7g\2\2\u00dc\u00dd\7h\2\2\u00dd"+ + "\u00de\7c\2\2\u00de\u00df\7w\2\2\u00df\u00e0\7n\2\2\u00e0\u00e1\7v\2\2"+ + "\u00e1\7\3\2\2\2\u00e2\u00e3\7h\2\2\u00e3\u00e4\7w\2\2\u00e4\u00e5\7p"+ + "\2\2\u00e5\u00e6\7e\2\2\u00e6\t\3\2\2\2\u00e7\u00e8\7k\2\2\u00e8\u00e9"+ + "\7p\2\2\u00e9\u00ea\7v\2\2\u00ea\u00eb\7g\2\2\u00eb\u00ec\7t\2\2\u00ec"+ + "\u00ed\7h\2\2\u00ed\u00ee\7c\2\2\u00ee\u00ef\7e\2\2\u00ef\u00f0\7g\2\2"+ + "\u00f0\13\3\2\2\2\u00f1\u00f2\7u\2\2\u00f2\u00f3\7g\2\2\u00f3\u00f4\7"+ + "n\2\2\u00f4\u00f5\7g\2\2\u00f5\u00f6\7e\2\2\u00f6\u00f7\7v\2\2\u00f7\r"+ + "\3\2\2\2\u00f8\u00f9\7e\2\2\u00f9\u00fa\7c\2\2\u00fa\u00fb\7u\2\2\u00fb"+ + "\u00fc\7g\2\2\u00fc\17\3\2\2\2\u00fd\u00fe\7f\2\2\u00fe\u00ff\7g\2\2\u00ff"+ + "\u0100\7h\2\2\u0100\u0101\7g\2\2\u0101\u0102\7t\2\2\u0102\21\3\2\2\2\u0103"+ + "\u0104\7i\2\2\u0104\u0105\7q\2\2\u0105\23\3\2\2\2\u0106\u0107\7o\2\2\u0107"+ + "\u0108\7c\2\2\u0108\u0109\7r\2\2\u0109\25\3\2\2\2\u010a\u010b\7u\2\2\u010b"+ + "\u010c\7v\2\2\u010c\u010d\7t\2\2\u010d\u010e\7w\2\2\u010e\u010f\7e\2\2"+ + "\u010f\u0110\7v\2\2\u0110\27\3\2\2\2\u0111\u0112\7e\2\2\u0112\u0113\7"+ + "j\2\2\u0113\u0114\7c\2\2\u0114\u0115\7p\2\2\u0115\31\3\2\2\2\u0116\u0117"+ + "\7g\2\2\u0117\u0118\7n\2\2\u0118\u0119\7u\2\2\u0119\u011a\7g\2\2\u011a"+ + "\33\3\2\2\2\u011b\u011c\7i\2\2\u011c\u011d\7q\2\2\u011d\u011e\7v\2\2\u011e"+ + "\u011f\7q\2\2\u011f\35\3\2\2\2\u0120\u0121\7r\2\2\u0121\u0122\7c\2\2\u0122"+ + "\u0123\7e\2\2\u0123\u0124\7m\2\2\u0124\u0125\7c\2\2\u0125\u0126\7i\2\2"+ + "\u0126\u0127\7g\2\2\u0127\37\3\2\2\2\u0128\u0129\7u\2\2\u0129\u012a\7"+ + "y\2\2\u012a\u012b\7k\2\2\u012b\u012c\7v\2\2\u012c\u012d\7e\2\2\u012d\u012e"+ + "\7j\2\2\u012e!\3\2\2\2\u012f\u0130\7e\2\2\u0130\u0131\7q\2\2\u0131\u0132"+ + "\7p\2\2\u0132\u0133\7u\2\2\u0133\u0134\7v\2\2\u0134#\3\2\2\2\u0135\u0136"+ + "\7h\2\2\u0136\u0137\7c\2\2\u0137\u0138\7n\2\2\u0138\u0139\7n\2\2\u0139"+ + "\u013a\7v\2\2\u013a\u013b\7j\2\2\u013b\u013c\7t\2\2\u013c\u013d\7q\2\2"+ + "\u013d\u013e\7w\2\2\u013e\u013f\7i\2\2\u013f\u0140\7j\2\2\u0140\u0141"+ + "\3\2\2\2\u0141\u0142\b\22\2\2\u0142%\3\2\2\2\u0143\u0144\7k\2\2\u0144"+ + "\u0145\7h\2\2\u0145\'\3\2\2\2\u0146\u0147\7t\2\2\u0147\u0148\7c\2\2\u0148"+ + "\u0149\7p\2\2\u0149\u014a\7i\2\2\u014a\u014b\7g\2\2\u014b)\3\2\2\2\u014c"+ + "\u014d\7v\2\2\u014d\u014e\7{\2\2\u014e\u014f\7r\2\2\u014f\u0150\7g\2\2"+ + "\u0150+\3\2\2\2\u0151\u0152\7e\2\2\u0152\u0153\7q\2\2\u0153\u0154\7p\2"+ + "\2\u0154\u0155\7v\2\2\u0155\u0156\7k\2\2\u0156\u0157\7p\2\2\u0157\u0158"+ + "\7w\2\2\u0158\u0159\7g\2\2\u0159\u015a\3\2\2\2\u015a\u015b\b\26\2\2\u015b"+ + "-\3\2\2\2\u015c\u015d\7h\2\2\u015d\u015e\7q\2\2\u015e\u015f\7t\2\2\u015f"+ + "/\3\2\2\2\u0160\u0161\7k\2\2\u0161\u0162\7o\2\2\u0162\u0163\7r\2\2\u0163"+ + "\u0164\7q\2\2\u0164\u0165\7t\2\2\u0165\u0166\7v\2\2\u0166\61\3\2\2\2\u0167"+ + "\u0168\7t\2\2\u0168\u0169\7g\2\2\u0169\u016a\7v\2\2\u016a\u016b\7w\2\2"+ + "\u016b\u016c\7t\2\2\u016c\u016d\7p\2\2\u016d\u016e\3\2\2\2\u016e\u016f"+ + "\b\31\2\2\u016f\63\3\2\2\2\u0170\u0171\7x\2\2\u0171\u0172\7c\2\2\u0172"+ + "\u0173\7t\2\2\u0173\65\3\2\2\2\u0174\u0175\7p\2\2\u0175\u0176\7k\2\2\u0176"+ + "\u0177\7n\2\2\u0177\u0178\3\2\2\2\u0178\u0179\b\33\2\2\u0179\67\3\2\2"+ + "\2\u017a\u017f\5\u00c2a\2\u017b\u017e\5\u00c2a\2\u017c\u017e\5\u00c4b"+ + "\2\u017d\u017b\3\2\2\2\u017d\u017c\3\2\2\2\u017e\u0181\3\2\2\2\u017f\u017d"+ + "\3\2\2\2\u017f\u0180\3\2\2\2\u0180\u0182\3\2\2\2\u0181\u017f\3\2\2\2\u0182"+ + "\u0183\b\34\2\2\u01839\3\2\2\2\u0184\u0185\7*\2\2\u0185;\3\2\2\2\u0186"+ + "\u0187\7+\2\2\u0187\u0188\3\2\2\2\u0188\u0189\b\36\2\2\u0189=\3\2\2\2"+ + "\u018a\u018b\7}\2\2\u018b?\3\2\2\2\u018c\u018d\7\177\2\2\u018d\u018e\3"+ + "\2\2\2\u018e\u018f\b \2\2\u018fA\3\2\2\2\u0190\u0191\7]\2\2\u0191C\3\2"+ + "\2\2\u0192\u0193\7_\2\2\u0193\u0194\3\2\2\2\u0194\u0195\b\"\2\2\u0195"+ + "E\3\2\2\2\u0196\u0197\7?\2\2\u0197G\3\2\2\2\u0198\u0199\7.\2\2\u0199I"+ + "\3\2\2\2\u019a\u019b\7=\2\2\u019bK\3\2\2\2\u019c\u019d\7<\2\2\u019dM\3"+ + "\2\2\2\u019e\u019f\7\60\2\2\u019fO\3\2\2\2\u01a0\u01a1\7-\2\2\u01a1\u01a2"+ + "\7-\2\2\u01a2\u01a3\3\2\2\2\u01a3\u01a4\b(\2\2\u01a4Q\3\2\2\2\u01a5\u01a6"+ + "\7/\2\2\u01a6\u01a7\7/\2\2\u01a7\u01a8\3\2\2\2\u01a8\u01a9\b)\2\2\u01a9"+ + "S\3\2\2\2\u01aa\u01ab\7<\2\2\u01ab\u01ac\7?\2\2\u01acU\3\2\2\2\u01ad\u01ae"+ + "\7\60\2\2\u01ae\u01af\7\60\2\2\u01af\u01b0\7\60\2\2\u01b0W\3\2\2\2\u01b1"+ + "\u01b2\7~\2\2\u01b2\u01b3\7~\2\2\u01b3Y\3\2\2\2\u01b4\u01b5\7(\2\2\u01b5"+ + "\u01b6\7(\2\2\u01b6[\3\2\2\2\u01b7\u01b8\7?\2\2\u01b8\u01b9\7?\2\2\u01b9"+ + "]\3\2\2\2\u01ba\u01bb\7#\2\2\u01bb\u01bc\7?\2\2\u01bc_\3\2\2\2\u01bd\u01be"+ + "\7>\2\2\u01bea\3\2\2\2\u01bf\u01c0\7>\2\2\u01c0\u01c1\7?\2\2\u01c1c\3"+ + "\2\2\2\u01c2\u01c3\7@\2\2\u01c3e\3\2\2\2\u01c4\u01c5\7@\2\2\u01c5\u01c6"+ + "\7?\2\2\u01c6g\3\2\2\2\u01c7\u01c8\7~\2\2\u01c8i\3\2\2\2\u01c9\u01ca\7"+ + "\61\2\2\u01cak\3\2\2\2\u01cb\u01cc\7\'\2\2\u01ccm\3\2\2\2\u01cd\u01ce"+ + "\7>\2\2\u01ce\u01cf\7>\2\2\u01cfo\3\2\2\2\u01d0\u01d1\7@\2\2\u01d1\u01d2"+ + "\7@\2\2\u01d2q\3\2\2\2\u01d3\u01d4\7(\2\2\u01d4\u01d5\7`\2\2\u01d5s\3"+ + "\2\2\2\u01d6\u01d7\7\u0080\2\2\u01d7u\3\2\2\2\u01d8\u01d9\7#\2\2\u01d9"+ + "w\3\2\2\2\u01da\u01db\7-\2\2\u01dby\3\2\2\2\u01dc\u01dd\7/\2\2\u01dd{"+ + "\3\2\2\2\u01de\u01df\7`\2\2\u01df}\3\2\2\2\u01e0\u01e1\7,\2\2\u01e1\177"+ + "\3\2\2\2\u01e2\u01e3\7(\2\2\u01e3\u0081\3\2\2\2\u01e4\u01e5\7>\2\2\u01e5"+ + "\u01e6\7/\2\2\u01e6\u0083\3\2\2\2\u01e7\u01f3\7\62\2\2\u01e8\u01ef\t\2"+ + "\2\2\u01e9\u01eb\7a\2\2\u01ea\u01e9\3\2\2\2\u01ea\u01eb\3\2\2\2\u01eb"+ + "\u01ec\3\2\2\2\u01ec\u01ee\t\3\2\2\u01ed\u01ea\3\2\2\2\u01ee\u01f1\3\2"+ + "\2\2\u01ef\u01ed\3\2\2\2\u01ef\u01f0\3\2\2\2\u01f0\u01f3\3\2\2\2\u01f1"+ + "\u01ef\3\2\2\2\u01f2\u01e7\3\2\2\2\u01f2\u01e8\3\2\2\2\u01f3\u01f4\3\2"+ + "\2\2\u01f4\u01f5\bB\2\2\u01f5\u0085\3\2\2\2\u01f6\u01f7\7\62\2\2\u01f7"+ + "\u01fc\t\4\2\2\u01f8\u01fa\7a\2\2\u01f9\u01f8\3\2\2\2\u01f9\u01fa\3\2"+ + "\2\2\u01fa\u01fb\3\2\2\2\u01fb\u01fd\5\u00be_\2\u01fc\u01f9\3\2\2\2\u01fd"+ + "\u01fe\3\2\2\2\u01fe\u01fc\3\2\2\2\u01fe\u01ff\3\2\2\2\u01ff\u0200\3\2"+ + "\2\2\u0200\u0201\bC\2\2\u0201\u0087\3\2\2\2\u0202\u0204\7\62\2\2\u0203"+ + "\u0205\t\5\2\2\u0204\u0203\3\2\2\2\u0204\u0205\3\2\2\2\u0205\u020a\3\2"+ + "\2\2\u0206\u0208\7a\2\2\u0207\u0206\3\2\2\2\u0207\u0208\3\2\2\2\u0208"+ + "\u0209\3\2\2\2\u0209\u020b\5\u00ba]\2\u020a\u0207\3\2\2\2\u020b\u020c"+ + "\3\2\2\2\u020c\u020a\3\2\2\2\u020c\u020d\3\2\2\2\u020d\u020e\3\2\2\2\u020e"+ + "\u020f\bD\2\2\u020f\u0089\3\2\2\2\u0210\u0211\7\62\2\2\u0211\u0216\t\6"+ + "\2\2\u0212\u0214\7a\2\2\u0213\u0212\3\2\2\2\u0213\u0214\3\2\2\2\u0214"+ + "\u0215\3\2\2\2\u0215\u0217\5\u00bc^\2\u0216\u0213\3\2\2\2\u0217\u0218"+ + "\3\2\2\2\u0218\u0216\3\2\2\2\u0218\u0219\3\2\2\2\u0219\u021a\3\2\2\2\u021a"+ + "\u021b\bE\2\2\u021b\u008b\3\2\2\2\u021c\u021f\5\u008eG\2\u021d\u021f\5"+ + "\u0090H\2\u021e\u021c\3\2\2\2\u021e\u021d\3\2\2\2\u021f\u0220\3\2\2\2"+ + "\u0220\u0221\bF\2\2\u0221\u008d\3\2\2\2\u0222\u022b\5\u00b8\\\2\u0223"+ + "\u0225\7\60\2\2\u0224\u0226\5\u00b8\\\2\u0225\u0224\3\2\2\2\u0225\u0226"+ + "\3\2\2\2\u0226\u0228\3\2\2\2\u0227\u0229\5\u00c0`\2\u0228\u0227\3\2\2"+ + "\2\u0228\u0229\3\2\2\2\u0229\u022c\3\2\2\2\u022a\u022c\5\u00c0`\2\u022b"+ + "\u0223\3\2\2\2\u022b\u022a\3\2\2\2\u022c\u0233\3\2\2\2\u022d\u022e\7\60"+ + "\2\2\u022e\u0230\5\u00b8\\\2\u022f\u0231\5\u00c0`\2\u0230\u022f\3\2\2"+ + "\2\u0230\u0231\3\2\2\2\u0231\u0233\3\2\2\2\u0232\u0222\3\2\2\2\u0232\u022d"+ + "\3\2\2\2\u0233\u008f\3\2\2\2\u0234\u0235\7\62\2\2\u0235\u0236\t\6\2\2"+ + "\u0236\u0237\5\u0092I\2\u0237\u0238\5\u0094J\2\u0238\u0091\3\2\2\2\u0239"+ + "\u023b\7a\2\2\u023a\u0239\3\2\2\2\u023a\u023b\3\2\2\2\u023b\u023c\3\2"+ + "\2\2\u023c\u023e\5\u00bc^\2\u023d\u023a\3\2\2\2\u023e\u023f\3\2\2\2\u023f"+ + "\u023d\3\2\2\2\u023f\u0240\3\2\2\2\u0240\u024b\3\2\2\2\u0241\u0248\7\60"+ + "\2\2\u0242\u0244\7a\2\2\u0243\u0242\3\2\2\2\u0243\u0244\3\2\2\2\u0244"+ + "\u0245\3\2\2\2\u0245\u0247\5\u00bc^\2\u0246\u0243\3\2\2\2\u0247\u024a"+ + "\3\2\2\2\u0248\u0246\3\2\2\2\u0248\u0249\3\2\2\2\u0249\u024c\3\2\2\2\u024a"+ + "\u0248\3\2\2\2\u024b\u0241\3\2\2\2\u024b\u024c\3\2\2\2\u024c\u0259\3\2"+ + "\2\2\u024d\u024e\7\60\2\2\u024e\u0255\5\u00bc^\2\u024f\u0251\7a\2\2\u0250"+ + "\u024f\3\2\2\2\u0250\u0251\3\2\2\2\u0251\u0252\3\2\2\2\u0252\u0254\5\u00bc"+ + "^\2\u0253\u0250\3\2\2\2\u0254\u0257\3\2\2\2\u0255\u0253\3\2\2\2\u0255"+ + "\u0256\3\2\2\2\u0256\u0259\3\2\2\2\u0257\u0255\3\2\2\2\u0258\u023d\3\2"+ + "\2\2\u0258\u024d\3\2\2\2\u0259\u0093\3\2\2\2\u025a\u025c\t\7\2\2\u025b"+ + "\u025d\t\b\2\2\u025c\u025b\3\2\2\2\u025c\u025d\3\2\2\2\u025d\u025e\3\2"+ + "\2\2\u025e\u025f\5\u00b8\\\2\u025f\u0095\3\2\2\2\u0260\u0266\5\u0084B"+ + "\2\u0261\u0266\5\u0086C\2\u0262\u0266\5\u0088D\2\u0263\u0266\5\u008aE"+ + "\2\u0264\u0266\5\u008cF\2\u0265\u0260\3\2\2\2\u0265\u0261\3\2\2\2\u0265"+ + "\u0262\3\2\2\2\u0265\u0263\3\2\2\2\u0265\u0264\3\2\2\2\u0266\u0267\3\2"+ + "\2\2\u0267\u0268\7k\2\2\u0268\u0269\3\2\2\2\u0269\u026a\bK\2\2\u026a\u0097"+ + "\3\2\2\2\u026b\u026e\7)\2\2\u026c\u026f\5\u00b4Z\2\u026d\u026f\5\u009c"+ + "N\2\u026e\u026c\3\2\2\2\u026e\u026d\3\2\2\2\u026f\u0270\3\2\2\2\u0270"+ + "\u0271\7)\2\2\u0271\u0099\3\2\2\2\u0272\u0273\5\u0098L\2\u0273\u0274\3"+ + "\2\2\2\u0274\u0275\bM\2\2\u0275\u009b\3\2\2\2\u0276\u0279\5\u009eO\2\u0277"+ + "\u0279\5\u00a0P\2\u0278\u0276\3\2\2\2\u0278\u0277\3\2\2\2\u0279\u009d"+ + "\3\2\2\2\u027a\u027b\7^\2\2\u027b\u027c\5\u00ba]\2\u027c\u027d\5\u00ba"+ + "]\2\u027d\u027e\5\u00ba]\2\u027e\u009f\3\2\2\2\u027f\u0280\7^\2\2\u0280"+ + "\u0281\7z\2\2\u0281\u0282\5\u00bc^\2\u0282\u0283\5\u00bc^\2\u0283\u00a1"+ + "\3\2\2\2\u0284\u0285\7^\2\2\u0285\u0286\7w\2\2\u0286\u0287\5\u00bc^\2"+ + "\u0287\u0288\5\u00bc^\2\u0288\u0289\5\u00bc^\2\u0289\u028a\5\u00bc^\2"+ + "\u028a\u00a3\3\2\2\2\u028b\u028c\7^\2\2\u028c\u028d\7W\2\2\u028d\u028e"+ + "\5\u00bc^\2\u028e\u028f\5\u00bc^\2\u028f\u0290\5\u00bc^\2\u0290\u0291"+ + "\5\u00bc^\2\u0291\u0292\5\u00bc^\2\u0292\u0293\5\u00bc^\2\u0293\u0294"+ + "\5\u00bc^\2\u0294\u0295\5\u00bc^\2\u0295\u00a5\3\2\2\2\u0296\u029a\7b"+ + "\2\2\u0297\u0299\n\t\2\2\u0298\u0297\3\2\2\2\u0299\u029c\3\2\2\2\u029a"+ + "\u0298\3\2\2\2\u029a\u029b\3\2\2\2\u029b\u029d\3\2\2\2\u029c\u029a\3\2"+ + "\2\2\u029d\u029e\7b\2\2\u029e\u029f\3\2\2\2\u029f\u02a0\bS\2\2\u02a0\u00a7"+ + "\3\2\2\2\u02a1\u02a6\7$\2\2\u02a2\u02a5\n\n\2\2\u02a3\u02a5\5\u00b6[\2"+ + "\u02a4\u02a2\3\2\2\2\u02a4\u02a3\3\2\2\2\u02a5\u02a8\3\2\2\2\u02a6\u02a4"+ + "\3\2\2\2\u02a6\u02a7\3\2\2\2\u02a7\u02a9\3\2\2\2\u02a8\u02a6\3\2\2\2\u02a9"+ + "\u02aa\7$\2\2\u02aa\u02ab\3\2\2\2\u02ab\u02ac\bT\2\2\u02ac\u00a9\3\2\2"+ + "\2\u02ad\u02af\t\13\2\2\u02ae\u02ad\3\2\2\2\u02af\u02b0\3\2\2\2\u02b0"+ + "\u02ae\3\2\2\2\u02b0\u02b1\3\2\2\2\u02b1\u02b2\3\2\2\2\u02b2\u02b3\bU"+ + "\3\2\u02b3\u00ab\3\2\2\2\u02b4\u02b5\7\61\2\2\u02b5\u02b6\7,\2\2\u02b6"+ + "\u02ba\3\2\2\2\u02b7\u02b9\13\2\2\2\u02b8\u02b7\3\2\2\2\u02b9\u02bc\3"+ + "\2\2\2\u02ba\u02bb\3\2\2\2\u02ba\u02b8\3\2\2\2\u02bb\u02bd\3\2\2\2\u02bc"+ + "\u02ba\3\2\2\2\u02bd\u02be\7,\2\2\u02be\u02bf\7\61\2\2\u02bf\u02c0\3\2"+ + "\2\2\u02c0\u02c1\bV\3\2\u02c1\u00ad\3\2\2\2\u02c2\u02c4\t\f\2\2\u02c3"+ + "\u02c2\3\2\2\2\u02c4\u02c5\3\2\2\2\u02c5\u02c3\3\2\2\2\u02c5\u02c6\3\2"+ + "\2\2\u02c6\u02c7\3\2\2\2\u02c7\u02c8\bW\3\2\u02c8\u00af\3\2\2\2\u02c9"+ + "\u02ca\7\61\2\2\u02ca\u02cb\7\61\2\2\u02cb\u02cf\3\2\2\2\u02cc\u02ce\n"+ + "\f\2\2\u02cd\u02cc\3\2\2\2\u02ce\u02d1\3\2\2\2\u02cf\u02cd\3\2\2\2\u02cf"+ + "\u02d0\3\2\2\2\u02d0\u02d2\3\2\2\2\u02d1\u02cf\3\2\2\2\u02d2\u02d3\bX"+ + "\3\2\u02d3\u00b1\3\2\2\2\u02d4\u02d6\7\17\2\2\u02d5\u02d4\3\2\2\2\u02d5"+ + "\u02d6\3\2\2\2\u02d6\u02d7\3\2\2\2\u02d7\u02e3\7\f\2\2\u02d8\u02da\7\17"+ + "\2\2\u02d9\u02d8\3\2\2\2\u02da\u02db\3\2\2\2\u02db\u02d9\3\2\2\2\u02db"+ + "\u02dc\3\2\2\2\u02dc\u02e3\3\2\2\2\u02dd\u02df\7\f\2\2\u02de\u02dd\3\2"+ + "\2\2\u02df\u02e0\3\2\2\2\u02e0\u02de\3\2\2\2\u02e0\u02e1\3\2\2\2\u02e1"+ + "\u02e3\3\2\2\2\u02e2\u02d5\3\2\2\2\u02e2\u02d9\3\2\2\2\u02e2\u02de\3\2"+ + "\2\2\u02e3\u00b3\3\2\2\2\u02e4\u02e9\n\r\2\2\u02e5\u02e9\5\u00a2Q\2\u02e6"+ + "\u02e9\5\u00a4R\2\u02e7\u02e9\5\u00b6[\2\u02e8\u02e4\3\2\2\2\u02e8\u02e5"+ + "\3\2\2\2\u02e8\u02e6\3\2\2\2\u02e8\u02e7\3\2\2\2\u02e9\u00b5\3\2\2\2\u02ea"+ + "\u0304\7^\2\2\u02eb\u02ec\7w\2\2\u02ec\u02ed\5\u00bc^\2\u02ed\u02ee\5"+ + "\u00bc^\2\u02ee\u02ef\5\u00bc^\2\u02ef\u02f0\5\u00bc^\2\u02f0\u0305\3"+ + "\2\2\2\u02f1\u02f2\7W\2\2\u02f2\u02f3\5\u00bc^\2\u02f3\u02f4\5\u00bc^"+ + "\2\u02f4\u02f5\5\u00bc^\2\u02f5\u02f6\5\u00bc^\2\u02f6\u02f7\5\u00bc^"+ + "\2\u02f7\u02f8\5\u00bc^\2\u02f8\u02f9\5\u00bc^\2\u02f9\u02fa\5\u00bc^"+ + "\2\u02fa\u0305\3\2\2\2\u02fb\u0305\t\16\2\2\u02fc\u02fd\5\u00ba]\2\u02fd"+ + "\u02fe\5\u00ba]\2\u02fe\u02ff\5\u00ba]\2\u02ff\u0305\3\2\2\2\u0300\u0301"+ + "\7z\2\2\u0301\u0302\5\u00bc^\2\u0302\u0303\5\u00bc^\2\u0303\u0305\3\2"+ + "\2\2\u0304\u02eb\3\2\2\2\u0304\u02f1\3\2\2\2\u0304\u02fb\3\2\2\2\u0304"+ + "\u02fc\3\2\2\2\u0304\u0300\3\2\2\2\u0305\u00b7\3\2\2\2\u0306\u030d\t\3"+ + "\2\2\u0307\u0309\7a\2\2\u0308\u0307\3\2\2\2\u0308\u0309\3\2\2\2\u0309"+ + "\u030a\3\2\2\2\u030a\u030c\t\3\2\2\u030b\u0308\3\2\2\2\u030c\u030f\3\2"+ + "\2\2\u030d\u030b\3\2\2\2\u030d\u030e\3\2\2\2\u030e\u00b9\3\2\2\2\u030f"+ + "\u030d\3\2\2\2\u0310\u0311\t\17\2\2\u0311\u00bb\3\2\2\2\u0312\u0313\t"+ + "\20\2\2\u0313\u00bd\3\2\2\2\u0314\u0315\t\21\2\2\u0315\u00bf\3\2\2\2\u0316"+ + "\u0318\t\22\2\2\u0317\u0319\t\b\2\2\u0318\u0317\3\2\2\2\u0318\u0319\3"+ + "\2\2\2\u0319\u031a\3\2\2\2\u031a\u031b\5\u00b8\\\2\u031b\u00c1\3\2\2\2"+ + "\u031c\u031f\5\u00c6c\2\u031d\u031f\7a\2\2\u031e\u031c\3\2\2\2\u031e\u031d"+ + "\3\2\2\2\u031f\u00c3\3\2\2\2\u0320\u0321\t\23\2\2\u0321\u00c5\3\2\2\2"+ + "\u0322\u0323\t\24\2\2\u0323\u00c7\3\2\2\2\u0324\u0326\t\13\2\2\u0325\u0324"+ + "\3\2\2\2\u0326\u0327\3\2\2\2\u0327\u0325\3\2\2\2\u0327\u0328\3\2\2\2\u0328"+ + "\u0329\3\2\2\2\u0329\u032a\bd\3\2\u032a\u00c9\3\2\2\2\u032b\u032c\7\61"+ + "\2\2\u032c\u032d\7,\2\2\u032d\u0331\3\2\2\2\u032e\u0330\n\f\2\2\u032f"+ + "\u032e\3\2\2\2\u0330\u0333\3\2\2\2\u0331\u0332\3\2\2\2\u0331\u032f\3\2"+ + "\2\2\u0332\u0334\3\2\2\2\u0333\u0331\3\2\2\2\u0334\u0335\7,\2\2\u0335"+ + "\u0336\7\61\2\2\u0336\u0337\3\2\2\2\u0337\u0338\be\3\2\u0338\u00cb\3\2"+ + "\2\2\u0339\u033a\7\61\2\2\u033a\u033b\7\61\2\2\u033b\u033f\3\2\2\2\u033c"+ + "\u033e\n\f\2\2\u033d\u033c\3\2\2\2\u033e\u0341\3\2\2\2\u033f\u033d\3\2"+ + "\2\2\u033f\u0340\3\2\2\2\u0340\u0342\3\2\2\2\u0341\u033f\3\2\2\2\u0342"+ + "\u0343\bf\3\2\u0343\u00cd\3\2\2\2\u0344\u0346\t\f\2\2\u0345\u0344\3\2"+ + "\2\2\u0346\u0347\3\2\2\2\u0347\u0345\3\2\2\2\u0347\u0348\3\2\2\2\u0348"+ + "\u0357\3\2\2\2\u0349\u0357\7=\2\2\u034a\u034b\7\61\2\2\u034b\u034c\7,"+ + "\2\2\u034c\u0350\3\2\2\2\u034d\u034f\13\2\2\2\u034e\u034d\3\2\2\2\u034f"+ + "\u0352\3\2\2\2\u0350\u0351\3\2\2\2\u0350\u034e\3\2\2\2\u0351\u0353\3\2"+ + "\2\2\u0352\u0350\3\2\2\2\u0353\u0354\7,\2\2\u0354\u0357\7\61\2\2\u0355"+ + "\u0357\7\2\2\3\u0356\u0345\3\2\2\2\u0356\u0349\3\2\2\2\u0356\u034a\3\2"+ + "\2\2\u0356\u0355\3\2\2\2\u0357\u0358\3\2\2\2\u0358\u0359\bg\4\2\u0359"+ + "\u00cf\3\2\2\2\u035a\u035b\3\2\2\2\u035b\u035c\3\2\2\2\u035c\u035d\bh"+ + "\4\2\u035d\u035e\bh\3\2\u035e\u00d1\3\2\2\29\2\3\u017d\u017f\u01ea\u01ef"+ + "\u01f2\u01f9\u01fe\u0204\u0207\u020c\u0213\u0218\u021e\u0225\u0228\u022b"+ + "\u0230\u0232\u023a\u023f\u0243\u0248\u024b\u0250\u0255\u0258\u025c\u0265"+ + "\u026e\u0278\u029a\u02a4\u02a6\u02b0\u02ba\u02c5\u02cf\u02d5\u02db\u02e0"+ + "\u02e2\u02e8\u0304\u0308\u030d\u0318\u031e\u0327\u0331\u033f\u0347\u0350"+ + "\u0356\5\4\3\2\2\3\2\4\2\2"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.tokens b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.tokens new file mode 100644 index 000000000..3d04e655a --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoLexer.tokens @@ -0,0 +1,153 @@ +BREAK=1 +DEFAULT=2 +FUNC=3 +INTERFACE=4 +SELECT=5 +CASE=6 +DEFER=7 +GO=8 +MAP=9 +STRUCT=10 +CHAN=11 +ELSE=12 +GOTO=13 +PACKAGE=14 +SWITCH=15 +CONST=16 +FALLTHROUGH=17 +IF=18 +RANGE=19 +TYPE=20 +CONTINUE=21 +FOR=22 +IMPORT=23 +RETURN=24 +VAR=25 +NIL_LIT=26 +IDENTIFIER=27 +L_PAREN=28 +R_PAREN=29 +L_CURLY=30 +R_CURLY=31 +L_BRACKET=32 +R_BRACKET=33 +ASSIGN=34 +COMMA=35 +SEMI=36 +COLON=37 +DOT=38 +PLUS_PLUS=39 +MINUS_MINUS=40 +DECLARE_ASSIGN=41 +ELLIPSIS=42 +LOGICAL_OR=43 +LOGICAL_AND=44 +EQUALS=45 +NOT_EQUALS=46 +LESS=47 +LESS_OR_EQUALS=48 +GREATER=49 +GREATER_OR_EQUALS=50 +OR=51 +DIV=52 +MOD=53 +LSHIFT=54 +RSHIFT=55 +BIT_CLEAR=56 +UNDERLYING=57 +EXCLAMATION=58 +PLUS=59 +MINUS=60 +CARET=61 +STAR=62 +AMPERSAND=63 +RECEIVE=64 +DECIMAL_LIT=65 +BINARY_LIT=66 +OCTAL_LIT=67 +HEX_LIT=68 +FLOAT_LIT=69 +DECIMAL_FLOAT_LIT=70 +HEX_FLOAT_LIT=71 +IMAGINARY_LIT=72 +RUNE_LIT=73 +BYTE_VALUE=74 +OCTAL_BYTE_VALUE=75 +HEX_BYTE_VALUE=76 +LITTLE_U_VALUE=77 +BIG_U_VALUE=78 +RAW_STRING_LIT=79 +INTERPRETED_STRING_LIT=80 +WS=81 +COMMENT=82 +TERMINATOR=83 +LINE_COMMENT=84 +NEWLINE=85 +WS_NLSEMI=86 +COMMENT_NLSEMI=87 +LINE_COMMENT_NLSEMI=88 +EOS=89 +OTHER=90 +'break'=1 +'default'=2 +'func'=3 +'interface'=4 +'select'=5 +'case'=6 +'defer'=7 +'go'=8 +'map'=9 +'struct'=10 +'chan'=11 +'else'=12 +'goto'=13 +'package'=14 +'switch'=15 +'const'=16 +'fallthrough'=17 +'if'=18 +'range'=19 +'type'=20 +'continue'=21 +'for'=22 +'import'=23 +'return'=24 +'var'=25 +'nil'=26 +'('=28 +')'=29 +'{'=30 +'}'=31 +'['=32 +']'=33 +'='=34 +','=35 +';'=36 +':'=37 +'.'=38 +'++'=39 +'--'=40 +':='=41 +'...'=42 +'||'=43 +'&&'=44 +'=='=45 +'!='=46 +'<'=47 +'<='=48 +'>'=49 +'>='=50 +'|'=51 +'/'=52 +'%'=53 +'<<'=54 +'>>'=55 +'&^'=56 +'~'=57 +'!'=58 +'+'=59 +'-'=60 +'^'=61 +'*'=62 +'&'=63 +'<-'=64 diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoMethod.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoMethod.java new file mode 100644 index 000000000..c5ca08e34 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoMethod.java @@ -0,0 +1,22 @@ +package run.mone.antlr.golang; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2024/1/29 16:56 + */ +@Data +@Builder +public class GoMethod { + + private String name; + + private List paramList; + + private String code; + +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParam.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParam.java new file mode 100644 index 000000000..10397309f --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParam.java @@ -0,0 +1,18 @@ +package run.mone.antlr.golang; + +import lombok.Builder; +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2024/1/29 17:02 + */ +@Data +@Builder +public class GoParam { + + private String name; + + private String type; + +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.interp b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.interp new file mode 100644 index 000000000..feb511177 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.interp @@ -0,0 +1,295 @@ +token literal names: +null +'break' +'default' +'func' +'interface' +'select' +'case' +'defer' +'go' +'map' +'struct' +'chan' +'else' +'goto' +'package' +'switch' +'const' +'fallthrough' +'if' +'range' +'type' +'continue' +'for' +'import' +'return' +'var' +'nil' +null +'(' +')' +'{' +'}' +'[' +']' +'=' +',' +';' +':' +'.' +'++' +'--' +':=' +'...' +'||' +'&&' +'==' +'!=' +'<' +'<=' +'>' +'>=' +'|' +'/' +'%' +'<<' +'>>' +'&^' +'~' +'!' +'+' +'-' +'^' +'*' +'&' +'<-' +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null +null + +token symbolic names: +null +BREAK +DEFAULT +FUNC +INTERFACE +SELECT +CASE +DEFER +GO +MAP +STRUCT +CHAN +ELSE +GOTO +PACKAGE +SWITCH +CONST +FALLTHROUGH +IF +RANGE +TYPE +CONTINUE +FOR +IMPORT +RETURN +VAR +NIL_LIT +IDENTIFIER +L_PAREN +R_PAREN +L_CURLY +R_CURLY +L_BRACKET +R_BRACKET +ASSIGN +COMMA +SEMI +COLON +DOT +PLUS_PLUS +MINUS_MINUS +DECLARE_ASSIGN +ELLIPSIS +LOGICAL_OR +LOGICAL_AND +EQUALS +NOT_EQUALS +LESS +LESS_OR_EQUALS +GREATER +GREATER_OR_EQUALS +OR +DIV +MOD +LSHIFT +RSHIFT +BIT_CLEAR +UNDERLYING +EXCLAMATION +PLUS +MINUS +CARET +STAR +AMPERSAND +RECEIVE +DECIMAL_LIT +BINARY_LIT +OCTAL_LIT +HEX_LIT +FLOAT_LIT +DECIMAL_FLOAT_LIT +HEX_FLOAT_LIT +IMAGINARY_LIT +RUNE_LIT +BYTE_VALUE +OCTAL_BYTE_VALUE +HEX_BYTE_VALUE +LITTLE_U_VALUE +BIG_U_VALUE +RAW_STRING_LIT +INTERPRETED_STRING_LIT +WS +COMMENT +TERMINATOR +LINE_COMMENT +NEWLINE +WS_NLSEMI +COMMENT_NLSEMI +LINE_COMMENT_NLSEMI +EOS +OTHER + +rule names: +sourceFile +packageClause +importDecl +importSpec +importPath +declaration +constDecl +constSpec +identifierList +expressionList +comment +typeDecl +typeSpec +aliasDecl +typeDef +typeParameters +typeParameterDecl +typeElement +typeTerm +functionDecl +methodDecl +receiver +varDecl +varSpec +block +statementList +statement +simpleStmt +expressionStmt +sendStmt +incDecStmt +assignment +assign_op +shortVarDecl +labeledStmt +returnStmt +breakStmt +continueStmt +gotoStmt +fallthroughStmt +deferStmt +ifStmt +switchStmt +exprSwitchStmt +exprCaseClause +exprSwitchCase +typeSwitchStmt +typeSwitchGuard +typeCaseClause +typeSwitchCase +typeList +selectStmt +commClause +commCase +recvStmt +forStmt +forClause +rangeClause +goStmt +type_ +typeArgs +typeName +typeLit +arrayType +arrayLength +elementType +pointerType +interfaceType +sliceType +mapType +channelType +methodSpec +functionType +signature +result +parameters +parameterDecl +expression +primaryExpr +conversion +operand +literal +basicLit +integer +operandName +qualifiedIdent +compositeLit +literalType +literalValue +elementList +keyedElement +key +element +structType +fieldDecl +string_ +embeddedField +functionLit +index +slice_ +typeAssertion +arguments +methodExpr +eos + + +atn: +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 92, 1025, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44, 9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9, 49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54, 4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4, 60, 9, 60, 4, 61, 9, 61, 4, 62, 9, 62, 4, 63, 9, 63, 4, 64, 9, 64, 4, 65, 9, 65, 4, 66, 9, 66, 4, 67, 9, 67, 4, 68, 9, 68, 4, 69, 9, 69, 4, 70, 9, 70, 4, 71, 9, 71, 4, 72, 9, 72, 4, 73, 9, 73, 4, 74, 9, 74, 4, 75, 9, 75, 4, 76, 9, 76, 4, 77, 9, 77, 4, 78, 9, 78, 4, 79, 9, 79, 4, 80, 9, 80, 4, 81, 9, 81, 4, 82, 9, 82, 4, 83, 9, 83, 4, 84, 9, 84, 4, 85, 9, 85, 4, 86, 9, 86, 4, 87, 9, 87, 4, 88, 9, 88, 4, 89, 9, 89, 4, 90, 9, 90, 4, 91, 9, 91, 4, 92, 9, 92, 4, 93, 9, 93, 4, 94, 9, 94, 4, 95, 9, 95, 4, 96, 9, 96, 4, 97, 9, 97, 4, 98, 9, 98, 4, 99, 9, 99, 4, 100, 9, 100, 4, 101, 9, 101, 4, 102, 9, 102, 4, 103, 9, 103, 4, 104, 9, 104, 4, 105, 9, 105, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 7, 2, 216, 10, 2, 12, 2, 14, 2, 219, 11, 2, 3, 2, 3, 2, 3, 2, 5, 2, 224, 10, 2, 3, 2, 3, 2, 7, 2, 228, 10, 2, 12, 2, 14, 2, 231, 11, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 7, 4, 244, 10, 4, 12, 4, 14, 4, 247, 11, 4, 3, 4, 5, 4, 250, 10, 4, 3, 5, 5, 5, 253, 10, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 5, 7, 262, 10, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 7, 8, 270, 10, 8, 12, 8, 14, 8, 273, 11, 8, 3, 8, 5, 8, 276, 10, 8, 3, 9, 3, 9, 5, 9, 280, 10, 9, 3, 9, 3, 9, 5, 9, 284, 10, 9, 3, 10, 3, 10, 3, 10, 7, 10, 289, 10, 10, 12, 10, 14, 10, 292, 11, 10, 3, 11, 3, 11, 3, 11, 7, 11, 297, 10, 11, 12, 11, 14, 11, 300, 11, 11, 3, 12, 3, 12, 3, 13, 7, 13, 305, 10, 13, 12, 13, 14, 13, 308, 11, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 7, 13, 316, 10, 13, 12, 13, 14, 13, 319, 11, 13, 3, 13, 5, 13, 322, 10, 13, 3, 14, 3, 14, 5, 14, 326, 10, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 5, 16, 334, 10, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 7, 17, 342, 10, 17, 12, 17, 14, 17, 345, 11, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 7, 19, 355, 10, 19, 12, 19, 14, 19, 358, 11, 19, 3, 20, 5, 20, 361, 10, 20, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 5, 21, 368, 10, 21, 3, 21, 3, 21, 5, 21, 372, 10, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 5, 22, 379, 10, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 7, 24, 389, 10, 24, 12, 24, 14, 24, 392, 11, 24, 3, 24, 5, 24, 395, 10, 24, 3, 25, 3, 25, 3, 25, 3, 25, 5, 25, 401, 10, 25, 3, 25, 3, 25, 5, 25, 405, 10, 25, 3, 26, 3, 26, 5, 26, 409, 10, 26, 3, 26, 3, 26, 3, 27, 5, 27, 414, 10, 27, 3, 27, 5, 27, 417, 10, 27, 3, 27, 5, 27, 420, 10, 27, 3, 27, 3, 27, 3, 27, 6, 27, 425, 10, 27, 13, 27, 14, 27, 426, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 5, 28, 444, 10, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 5, 29, 451, 10, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 5, 34, 467, 10, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 36, 3, 36, 3, 36, 5, 36, 478, 10, 36, 3, 37, 3, 37, 5, 37, 482, 10, 37, 3, 38, 3, 38, 5, 38, 486, 10, 38, 3, 39, 3, 39, 5, 39, 490, 10, 39, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 5, 43, 509, 10, 43, 3, 43, 3, 43, 3, 43, 3, 43, 5, 43, 515, 10, 43, 5, 43, 517, 10, 43, 3, 44, 3, 44, 5, 44, 521, 10, 44, 3, 45, 3, 45, 5, 45, 525, 10, 45, 3, 45, 5, 45, 528, 10, 45, 3, 45, 3, 45, 5, 45, 532, 10, 45, 5, 45, 534, 10, 45, 3, 45, 3, 45, 7, 45, 538, 10, 45, 12, 45, 14, 45, 541, 11, 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 5, 46, 548, 10, 46, 3, 47, 3, 47, 3, 47, 5, 47, 553, 10, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 5, 48, 564, 10, 48, 3, 48, 3, 48, 7, 48, 568, 10, 48, 12, 48, 14, 48, 571, 11, 48, 3, 48, 3, 48, 3, 49, 3, 49, 5, 49, 577, 10, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 5, 50, 588, 10, 50, 3, 51, 3, 51, 3, 51, 5, 51, 593, 10, 51, 3, 52, 3, 52, 5, 52, 597, 10, 52, 3, 52, 3, 52, 3, 52, 5, 52, 602, 10, 52, 7, 52, 604, 10, 52, 12, 52, 14, 52, 607, 11, 52, 3, 53, 3, 53, 3, 53, 7, 53, 612, 10, 53, 12, 53, 14, 53, 615, 11, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 5, 54, 622, 10, 54, 3, 55, 3, 55, 3, 55, 5, 55, 627, 10, 55, 3, 55, 5, 55, 630, 10, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 5, 56, 638, 10, 56, 3, 56, 3, 56, 3, 57, 3, 57, 5, 57, 644, 10, 57, 3, 57, 3, 57, 5, 57, 648, 10, 57, 5, 57, 650, 10, 57, 3, 57, 3, 57, 3, 58, 5, 58, 655, 10, 58, 3, 58, 3, 58, 5, 58, 659, 10, 58, 3, 58, 3, 58, 5, 58, 663, 10, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 5, 59, 671, 10, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 5, 61, 681, 10, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 5, 61, 688, 10, 61, 3, 62, 3, 62, 3, 62, 5, 62, 693, 10, 62, 3, 62, 3, 62, 3, 63, 3, 63, 5, 63, 699, 10, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 3, 64, 5, 64, 709, 10, 64, 3, 65, 3, 65, 3, 65, 3, 65, 3, 65, 3, 66, 3, 66, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 69, 3, 69, 3, 69, 3, 69, 5, 69, 727, 10, 69, 3, 69, 3, 69, 7, 69, 731, 10, 69, 12, 69, 14, 69, 734, 11, 69, 3, 69, 3, 69, 3, 70, 3, 70, 3, 70, 3, 70, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 71, 3, 72, 3, 72, 3, 72, 3, 72, 3, 72, 5, 72, 753, 10, 72, 3, 72, 3, 72, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 3, 73, 5, 73, 763, 10, 73, 3, 74, 3, 74, 3, 74, 3, 75, 3, 75, 5, 75, 770, 10, 75, 3, 76, 3, 76, 5, 76, 774, 10, 76, 3, 77, 3, 77, 3, 77, 3, 77, 7, 77, 780, 10, 77, 12, 77, 14, 77, 783, 11, 77, 3, 77, 5, 77, 786, 10, 77, 5, 77, 788, 10, 77, 3, 77, 3, 77, 3, 78, 5, 78, 793, 10, 78, 3, 78, 5, 78, 796, 10, 78, 3, 78, 3, 78, 3, 79, 3, 79, 3, 79, 3, 79, 5, 79, 804, 10, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 3, 79, 7, 79, 821, 10, 79, 12, 79, 14, 79, 824, 11, 79, 3, 80, 3, 80, 3, 80, 3, 80, 5, 80, 830, 10, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 3, 80, 5, 80, 839, 10, 80, 7, 80, 841, 10, 80, 12, 80, 14, 80, 844, 11, 80, 3, 81, 3, 81, 3, 81, 3, 81, 5, 81, 850, 10, 81, 3, 81, 3, 81, 3, 82, 3, 82, 3, 82, 5, 82, 857, 10, 82, 3, 82, 3, 82, 3, 82, 3, 82, 5, 82, 863, 10, 82, 3, 83, 3, 83, 3, 83, 5, 83, 868, 10, 83, 3, 84, 3, 84, 3, 84, 3, 84, 5, 84, 874, 10, 84, 3, 85, 3, 85, 3, 86, 3, 86, 3, 87, 3, 87, 3, 87, 3, 87, 3, 88, 3, 88, 3, 88, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 3, 89, 5, 89, 897, 10, 89, 5, 89, 899, 10, 89, 3, 90, 3, 90, 3, 90, 5, 90, 904, 10, 90, 5, 90, 906, 10, 90, 3, 90, 3, 90, 3, 91, 3, 91, 3, 91, 7, 91, 913, 10, 91, 12, 91, 14, 91, 916, 11, 91, 3, 92, 3, 92, 3, 92, 5, 92, 921, 10, 92, 3, 92, 3, 92, 3, 93, 3, 93, 5, 93, 927, 10, 93, 3, 94, 3, 94, 5, 94, 931, 10, 94, 3, 95, 3, 95, 3, 95, 3, 95, 3, 95, 7, 95, 938, 10, 95, 12, 95, 14, 95, 941, 11, 95, 3, 95, 3, 95, 3, 96, 3, 96, 3, 96, 3, 96, 5, 96, 949, 10, 96, 3, 96, 5, 96, 952, 10, 96, 3, 97, 3, 97, 3, 98, 5, 98, 957, 10, 98, 3, 98, 3, 98, 5, 98, 961, 10, 98, 3, 99, 3, 99, 3, 99, 3, 99, 3, 100, 3, 100, 3, 100, 3, 100, 3, 101, 3, 101, 5, 101, 973, 10, 101, 3, 101, 3, 101, 5, 101, 977, 10, 101, 3, 101, 5, 101, 980, 10, 101, 3, 101, 3, 101, 3, 101, 3, 101, 3, 101, 5, 101, 987, 10, 101, 3, 101, 3, 101, 3, 102, 3, 102, 3, 102, 3, 102, 3, 102, 3, 103, 3, 103, 3, 103, 3, 103, 3, 103, 5, 103, 1001, 10, 103, 5, 103, 1003, 10, 103, 3, 103, 5, 103, 1006, 10, 103, 3, 103, 5, 103, 1009, 10, 103, 5, 103, 1011, 10, 103, 3, 103, 3, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 105, 3, 105, 3, 105, 3, 105, 5, 105, 1023, 10, 105, 3, 105, 2, 4, 156, 158, 106, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 2, 12, 4, 2, 29, 29, 40, 40, 4, 2, 84, 84, 86, 86, 3, 2, 41, 42, 4, 2, 53, 58, 61, 65, 3, 2, 60, 66, 4, 2, 54, 58, 64, 65, 4, 2, 53, 53, 61, 63, 3, 2, 47, 52, 4, 2, 67, 70, 74, 75, 3, 2, 81, 82, 2, 1090, 2, 210, 3, 2, 2, 2, 4, 234, 3, 2, 2, 2, 6, 237, 3, 2, 2, 2, 8, 252, 3, 2, 2, 2, 10, 256, 3, 2, 2, 2, 12, 261, 3, 2, 2, 2, 14, 263, 3, 2, 2, 2, 16, 277, 3, 2, 2, 2, 18, 285, 3, 2, 2, 2, 20, 293, 3, 2, 2, 2, 22, 301, 3, 2, 2, 2, 24, 306, 3, 2, 2, 2, 26, 325, 3, 2, 2, 2, 28, 327, 3, 2, 2, 2, 30, 331, 3, 2, 2, 2, 32, 337, 3, 2, 2, 2, 34, 348, 3, 2, 2, 2, 36, 351, 3, 2, 2, 2, 38, 360, 3, 2, 2, 2, 40, 364, 3, 2, 2, 2, 42, 373, 3, 2, 2, 2, 44, 380, 3, 2, 2, 2, 46, 382, 3, 2, 2, 2, 48, 396, 3, 2, 2, 2, 50, 406, 3, 2, 2, 2, 52, 424, 3, 2, 2, 2, 54, 443, 3, 2, 2, 2, 56, 450, 3, 2, 2, 2, 58, 452, 3, 2, 2, 2, 60, 454, 3, 2, 2, 2, 62, 458, 3, 2, 2, 2, 64, 461, 3, 2, 2, 2, 66, 466, 3, 2, 2, 2, 68, 470, 3, 2, 2, 2, 70, 474, 3, 2, 2, 2, 72, 479, 3, 2, 2, 2, 74, 483, 3, 2, 2, 2, 76, 487, 3, 2, 2, 2, 78, 491, 3, 2, 2, 2, 80, 494, 3, 2, 2, 2, 82, 496, 3, 2, 2, 2, 84, 499, 3, 2, 2, 2, 86, 520, 3, 2, 2, 2, 88, 522, 3, 2, 2, 2, 90, 544, 3, 2, 2, 2, 92, 552, 3, 2, 2, 2, 94, 554, 3, 2, 2, 2, 96, 576, 3, 2, 2, 2, 98, 584, 3, 2, 2, 2, 100, 592, 3, 2, 2, 2, 102, 596, 3, 2, 2, 2, 104, 608, 3, 2, 2, 2, 106, 618, 3, 2, 2, 2, 108, 629, 3, 2, 2, 2, 110, 637, 3, 2, 2, 2, 112, 641, 3, 2, 2, 2, 114, 654, 3, 2, 2, 2, 116, 670, 3, 2, 2, 2, 118, 675, 3, 2, 2, 2, 120, 687, 3, 2, 2, 2, 122, 689, 3, 2, 2, 2, 124, 698, 3, 2, 2, 2, 126, 708, 3, 2, 2, 2, 128, 710, 3, 2, 2, 2, 130, 715, 3, 2, 2, 2, 132, 717, 3, 2, 2, 2, 134, 719, 3, 2, 2, 2, 136, 722, 3, 2, 2, 2, 138, 737, 3, 2, 2, 2, 140, 741, 3, 2, 2, 2, 142, 752, 3, 2, 2, 2, 144, 762, 3, 2, 2, 2, 146, 764, 3, 2, 2, 2, 148, 767, 3, 2, 2, 2, 150, 773, 3, 2, 2, 2, 152, 775, 3, 2, 2, 2, 154, 792, 3, 2, 2, 2, 156, 803, 3, 2, 2, 2, 158, 829, 3, 2, 2, 2, 160, 845, 3, 2, 2, 2, 162, 862, 3, 2, 2, 2, 164, 867, 3, 2, 2, 2, 166, 873, 3, 2, 2, 2, 168, 875, 3, 2, 2, 2, 170, 877, 3, 2, 2, 2, 172, 879, 3, 2, 2, 2, 174, 883, 3, 2, 2, 2, 176, 898, 3, 2, 2, 2, 178, 900, 3, 2, 2, 2, 180, 909, 3, 2, 2, 2, 182, 920, 3, 2, 2, 2, 184, 926, 3, 2, 2, 2, 186, 930, 3, 2, 2, 2, 188, 932, 3, 2, 2, 2, 190, 948, 3, 2, 2, 2, 192, 953, 3, 2, 2, 2, 194, 956, 3, 2, 2, 2, 196, 962, 3, 2, 2, 2, 198, 966, 3, 2, 2, 2, 200, 970, 3, 2, 2, 2, 202, 990, 3, 2, 2, 2, 204, 995, 3, 2, 2, 2, 206, 1014, 3, 2, 2, 2, 208, 1022, 3, 2, 2, 2, 210, 211, 5, 4, 3, 2, 211, 217, 5, 208, 105, 2, 212, 213, 5, 6, 4, 2, 213, 214, 5, 208, 105, 2, 214, 216, 3, 2, 2, 2, 215, 212, 3, 2, 2, 2, 216, 219, 3, 2, 2, 2, 217, 215, 3, 2, 2, 2, 217, 218, 3, 2, 2, 2, 218, 229, 3, 2, 2, 2, 219, 217, 3, 2, 2, 2, 220, 224, 5, 40, 21, 2, 221, 224, 5, 42, 22, 2, 222, 224, 5, 12, 7, 2, 223, 220, 3, 2, 2, 2, 223, 221, 3, 2, 2, 2, 223, 222, 3, 2, 2, 2, 224, 225, 3, 2, 2, 2, 225, 226, 5, 208, 105, 2, 226, 228, 3, 2, 2, 2, 227, 223, 3, 2, 2, 2, 228, 231, 3, 2, 2, 2, 229, 227, 3, 2, 2, 2, 229, 230, 3, 2, 2, 2, 230, 232, 3, 2, 2, 2, 231, 229, 3, 2, 2, 2, 232, 233, 7, 2, 2, 3, 233, 3, 3, 2, 2, 2, 234, 235, 7, 16, 2, 2, 235, 236, 7, 29, 2, 2, 236, 5, 3, 2, 2, 2, 237, 249, 7, 25, 2, 2, 238, 250, 5, 8, 5, 2, 239, 245, 7, 30, 2, 2, 240, 241, 5, 8, 5, 2, 241, 242, 5, 208, 105, 2, 242, 244, 3, 2, 2, 2, 243, 240, 3, 2, 2, 2, 244, 247, 3, 2, 2, 2, 245, 243, 3, 2, 2, 2, 245, 246, 3, 2, 2, 2, 246, 248, 3, 2, 2, 2, 247, 245, 3, 2, 2, 2, 248, 250, 7, 31, 2, 2, 249, 238, 3, 2, 2, 2, 249, 239, 3, 2, 2, 2, 250, 7, 3, 2, 2, 2, 251, 253, 9, 2, 2, 2, 252, 251, 3, 2, 2, 2, 252, 253, 3, 2, 2, 2, 253, 254, 3, 2, 2, 2, 254, 255, 5, 10, 6, 2, 255, 9, 3, 2, 2, 2, 256, 257, 5, 192, 97, 2, 257, 11, 3, 2, 2, 2, 258, 262, 5, 14, 8, 2, 259, 262, 5, 24, 13, 2, 260, 262, 5, 46, 24, 2, 261, 258, 3, 2, 2, 2, 261, 259, 3, 2, 2, 2, 261, 260, 3, 2, 2, 2, 262, 13, 3, 2, 2, 2, 263, 275, 7, 18, 2, 2, 264, 276, 5, 16, 9, 2, 265, 271, 7, 30, 2, 2, 266, 267, 5, 16, 9, 2, 267, 268, 5, 208, 105, 2, 268, 270, 3, 2, 2, 2, 269, 266, 3, 2, 2, 2, 270, 273, 3, 2, 2, 2, 271, 269, 3, 2, 2, 2, 271, 272, 3, 2, 2, 2, 272, 274, 3, 2, 2, 2, 273, 271, 3, 2, 2, 2, 274, 276, 7, 31, 2, 2, 275, 264, 3, 2, 2, 2, 275, 265, 3, 2, 2, 2, 276, 15, 3, 2, 2, 2, 277, 283, 5, 18, 10, 2, 278, 280, 5, 120, 61, 2, 279, 278, 3, 2, 2, 2, 279, 280, 3, 2, 2, 2, 280, 281, 3, 2, 2, 2, 281, 282, 7, 36, 2, 2, 282, 284, 5, 20, 11, 2, 283, 279, 3, 2, 2, 2, 283, 284, 3, 2, 2, 2, 284, 17, 3, 2, 2, 2, 285, 290, 7, 29, 2, 2, 286, 287, 7, 37, 2, 2, 287, 289, 7, 29, 2, 2, 288, 286, 3, 2, 2, 2, 289, 292, 3, 2, 2, 2, 290, 288, 3, 2, 2, 2, 290, 291, 3, 2, 2, 2, 291, 19, 3, 2, 2, 2, 292, 290, 3, 2, 2, 2, 293, 298, 5, 156, 79, 2, 294, 295, 7, 37, 2, 2, 295, 297, 5, 156, 79, 2, 296, 294, 3, 2, 2, 2, 297, 300, 3, 2, 2, 2, 298, 296, 3, 2, 2, 2, 298, 299, 3, 2, 2, 2, 299, 21, 3, 2, 2, 2, 300, 298, 3, 2, 2, 2, 301, 302, 9, 3, 2, 2, 302, 23, 3, 2, 2, 2, 303, 305, 5, 22, 12, 2, 304, 303, 3, 2, 2, 2, 305, 308, 3, 2, 2, 2, 306, 304, 3, 2, 2, 2, 306, 307, 3, 2, 2, 2, 307, 309, 3, 2, 2, 2, 308, 306, 3, 2, 2, 2, 309, 321, 7, 22, 2, 2, 310, 322, 5, 26, 14, 2, 311, 317, 7, 30, 2, 2, 312, 313, 5, 26, 14, 2, 313, 314, 5, 208, 105, 2, 314, 316, 3, 2, 2, 2, 315, 312, 3, 2, 2, 2, 316, 319, 3, 2, 2, 2, 317, 315, 3, 2, 2, 2, 317, 318, 3, 2, 2, 2, 318, 320, 3, 2, 2, 2, 319, 317, 3, 2, 2, 2, 320, 322, 7, 31, 2, 2, 321, 310, 3, 2, 2, 2, 321, 311, 3, 2, 2, 2, 322, 25, 3, 2, 2, 2, 323, 326, 5, 28, 15, 2, 324, 326, 5, 30, 16, 2, 325, 323, 3, 2, 2, 2, 325, 324, 3, 2, 2, 2, 326, 27, 3, 2, 2, 2, 327, 328, 7, 29, 2, 2, 328, 329, 7, 36, 2, 2, 329, 330, 5, 120, 61, 2, 330, 29, 3, 2, 2, 2, 331, 333, 7, 29, 2, 2, 332, 334, 5, 32, 17, 2, 333, 332, 3, 2, 2, 2, 333, 334, 3, 2, 2, 2, 334, 335, 3, 2, 2, 2, 335, 336, 5, 120, 61, 2, 336, 31, 3, 2, 2, 2, 337, 338, 7, 34, 2, 2, 338, 343, 5, 34, 18, 2, 339, 340, 7, 37, 2, 2, 340, 342, 5, 34, 18, 2, 341, 339, 3, 2, 2, 2, 342, 345, 3, 2, 2, 2, 343, 341, 3, 2, 2, 2, 343, 344, 3, 2, 2, 2, 344, 346, 3, 2, 2, 2, 345, 343, 3, 2, 2, 2, 346, 347, 7, 35, 2, 2, 347, 33, 3, 2, 2, 2, 348, 349, 5, 18, 10, 2, 349, 350, 5, 36, 19, 2, 350, 35, 3, 2, 2, 2, 351, 356, 5, 38, 20, 2, 352, 353, 7, 53, 2, 2, 353, 355, 5, 38, 20, 2, 354, 352, 3, 2, 2, 2, 355, 358, 3, 2, 2, 2, 356, 354, 3, 2, 2, 2, 356, 357, 3, 2, 2, 2, 357, 37, 3, 2, 2, 2, 358, 356, 3, 2, 2, 2, 359, 361, 7, 59, 2, 2, 360, 359, 3, 2, 2, 2, 360, 361, 3, 2, 2, 2, 361, 362, 3, 2, 2, 2, 362, 363, 5, 120, 61, 2, 363, 39, 3, 2, 2, 2, 364, 365, 7, 5, 2, 2, 365, 367, 7, 29, 2, 2, 366, 368, 5, 32, 17, 2, 367, 366, 3, 2, 2, 2, 367, 368, 3, 2, 2, 2, 368, 369, 3, 2, 2, 2, 369, 371, 5, 148, 75, 2, 370, 372, 5, 50, 26, 2, 371, 370, 3, 2, 2, 2, 371, 372, 3, 2, 2, 2, 372, 41, 3, 2, 2, 2, 373, 374, 7, 5, 2, 2, 374, 375, 5, 44, 23, 2, 375, 376, 7, 29, 2, 2, 376, 378, 5, 148, 75, 2, 377, 379, 5, 50, 26, 2, 378, 377, 3, 2, 2, 2, 378, 379, 3, 2, 2, 2, 379, 43, 3, 2, 2, 2, 380, 381, 5, 152, 77, 2, 381, 45, 3, 2, 2, 2, 382, 394, 7, 27, 2, 2, 383, 395, 5, 48, 25, 2, 384, 390, 7, 30, 2, 2, 385, 386, 5, 48, 25, 2, 386, 387, 5, 208, 105, 2, 387, 389, 3, 2, 2, 2, 388, 385, 3, 2, 2, 2, 389, 392, 3, 2, 2, 2, 390, 388, 3, 2, 2, 2, 390, 391, 3, 2, 2, 2, 391, 393, 3, 2, 2, 2, 392, 390, 3, 2, 2, 2, 393, 395, 7, 31, 2, 2, 394, 383, 3, 2, 2, 2, 394, 384, 3, 2, 2, 2, 395, 47, 3, 2, 2, 2, 396, 404, 5, 18, 10, 2, 397, 400, 5, 120, 61, 2, 398, 399, 7, 36, 2, 2, 399, 401, 5, 20, 11, 2, 400, 398, 3, 2, 2, 2, 400, 401, 3, 2, 2, 2, 401, 405, 3, 2, 2, 2, 402, 403, 7, 36, 2, 2, 403, 405, 5, 20, 11, 2, 404, 397, 3, 2, 2, 2, 404, 402, 3, 2, 2, 2, 405, 49, 3, 2, 2, 2, 406, 408, 7, 32, 2, 2, 407, 409, 5, 52, 27, 2, 408, 407, 3, 2, 2, 2, 408, 409, 3, 2, 2, 2, 409, 410, 3, 2, 2, 2, 410, 411, 7, 33, 2, 2, 411, 51, 3, 2, 2, 2, 412, 414, 7, 38, 2, 2, 413, 412, 3, 2, 2, 2, 413, 414, 3, 2, 2, 2, 414, 420, 3, 2, 2, 2, 415, 417, 7, 91, 2, 2, 416, 415, 3, 2, 2, 2, 416, 417, 3, 2, 2, 2, 417, 420, 3, 2, 2, 2, 418, 420, 6, 27, 2, 2, 419, 413, 3, 2, 2, 2, 419, 416, 3, 2, 2, 2, 419, 418, 3, 2, 2, 2, 420, 421, 3, 2, 2, 2, 421, 422, 5, 54, 28, 2, 422, 423, 5, 208, 105, 2, 423, 425, 3, 2, 2, 2, 424, 419, 3, 2, 2, 2, 425, 426, 3, 2, 2, 2, 426, 424, 3, 2, 2, 2, 426, 427, 3, 2, 2, 2, 427, 53, 3, 2, 2, 2, 428, 444, 5, 12, 7, 2, 429, 444, 5, 70, 36, 2, 430, 444, 5, 56, 29, 2, 431, 444, 5, 118, 60, 2, 432, 444, 5, 72, 37, 2, 433, 444, 5, 74, 38, 2, 434, 444, 5, 76, 39, 2, 435, 444, 5, 78, 40, 2, 436, 444, 5, 80, 41, 2, 437, 444, 5, 50, 26, 2, 438, 444, 5, 84, 43, 2, 439, 444, 5, 86, 44, 2, 440, 444, 5, 104, 53, 2, 441, 444, 5, 112, 57, 2, 442, 444, 5, 82, 42, 2, 443, 428, 3, 2, 2, 2, 443, 429, 3, 2, 2, 2, 443, 430, 3, 2, 2, 2, 443, 431, 3, 2, 2, 2, 443, 432, 3, 2, 2, 2, 443, 433, 3, 2, 2, 2, 443, 434, 3, 2, 2, 2, 443, 435, 3, 2, 2, 2, 443, 436, 3, 2, 2, 2, 443, 437, 3, 2, 2, 2, 443, 438, 3, 2, 2, 2, 443, 439, 3, 2, 2, 2, 443, 440, 3, 2, 2, 2, 443, 441, 3, 2, 2, 2, 443, 442, 3, 2, 2, 2, 444, 55, 3, 2, 2, 2, 445, 451, 5, 60, 31, 2, 446, 451, 5, 62, 32, 2, 447, 451, 5, 64, 33, 2, 448, 451, 5, 58, 30, 2, 449, 451, 5, 68, 35, 2, 450, 445, 3, 2, 2, 2, 450, 446, 3, 2, 2, 2, 450, 447, 3, 2, 2, 2, 450, 448, 3, 2, 2, 2, 450, 449, 3, 2, 2, 2, 451, 57, 3, 2, 2, 2, 452, 453, 5, 156, 79, 2, 453, 59, 3, 2, 2, 2, 454, 455, 5, 156, 79, 2, 455, 456, 7, 66, 2, 2, 456, 457, 5, 156, 79, 2, 457, 61, 3, 2, 2, 2, 458, 459, 5, 156, 79, 2, 459, 460, 9, 4, 2, 2, 460, 63, 3, 2, 2, 2, 461, 462, 5, 20, 11, 2, 462, 463, 5, 66, 34, 2, 463, 464, 5, 20, 11, 2, 464, 65, 3, 2, 2, 2, 465, 467, 9, 5, 2, 2, 466, 465, 3, 2, 2, 2, 466, 467, 3, 2, 2, 2, 467, 468, 3, 2, 2, 2, 468, 469, 7, 36, 2, 2, 469, 67, 3, 2, 2, 2, 470, 471, 5, 18, 10, 2, 471, 472, 7, 43, 2, 2, 472, 473, 5, 20, 11, 2, 473, 69, 3, 2, 2, 2, 474, 475, 7, 29, 2, 2, 475, 477, 7, 39, 2, 2, 476, 478, 5, 54, 28, 2, 477, 476, 3, 2, 2, 2, 477, 478, 3, 2, 2, 2, 478, 71, 3, 2, 2, 2, 479, 481, 7, 26, 2, 2, 480, 482, 5, 20, 11, 2, 481, 480, 3, 2, 2, 2, 481, 482, 3, 2, 2, 2, 482, 73, 3, 2, 2, 2, 483, 485, 7, 3, 2, 2, 484, 486, 7, 29, 2, 2, 485, 484, 3, 2, 2, 2, 485, 486, 3, 2, 2, 2, 486, 75, 3, 2, 2, 2, 487, 489, 7, 23, 2, 2, 488, 490, 7, 29, 2, 2, 489, 488, 3, 2, 2, 2, 489, 490, 3, 2, 2, 2, 490, 77, 3, 2, 2, 2, 491, 492, 7, 15, 2, 2, 492, 493, 7, 29, 2, 2, 493, 79, 3, 2, 2, 2, 494, 495, 7, 19, 2, 2, 495, 81, 3, 2, 2, 2, 496, 497, 7, 9, 2, 2, 497, 498, 5, 156, 79, 2, 498, 83, 3, 2, 2, 2, 499, 508, 7, 20, 2, 2, 500, 509, 5, 156, 79, 2, 501, 502, 5, 208, 105, 2, 502, 503, 5, 156, 79, 2, 503, 509, 3, 2, 2, 2, 504, 505, 5, 56, 29, 2, 505, 506, 5, 208, 105, 2, 506, 507, 5, 156, 79, 2, 507, 509, 3, 2, 2, 2, 508, 500, 3, 2, 2, 2, 508, 501, 3, 2, 2, 2, 508, 504, 3, 2, 2, 2, 509, 510, 3, 2, 2, 2, 510, 516, 5, 50, 26, 2, 511, 514, 7, 14, 2, 2, 512, 515, 5, 84, 43, 2, 513, 515, 5, 50, 26, 2, 514, 512, 3, 2, 2, 2, 514, 513, 3, 2, 2, 2, 515, 517, 3, 2, 2, 2, 516, 511, 3, 2, 2, 2, 516, 517, 3, 2, 2, 2, 517, 85, 3, 2, 2, 2, 518, 521, 5, 88, 45, 2, 519, 521, 5, 94, 48, 2, 520, 518, 3, 2, 2, 2, 520, 519, 3, 2, 2, 2, 521, 87, 3, 2, 2, 2, 522, 533, 7, 17, 2, 2, 523, 525, 5, 156, 79, 2, 524, 523, 3, 2, 2, 2, 524, 525, 3, 2, 2, 2, 525, 534, 3, 2, 2, 2, 526, 528, 5, 56, 29, 2, 527, 526, 3, 2, 2, 2, 527, 528, 3, 2, 2, 2, 528, 529, 3, 2, 2, 2, 529, 531, 5, 208, 105, 2, 530, 532, 5, 156, 79, 2, 531, 530, 3, 2, 2, 2, 531, 532, 3, 2, 2, 2, 532, 534, 3, 2, 2, 2, 533, 524, 3, 2, 2, 2, 533, 527, 3, 2, 2, 2, 534, 535, 3, 2, 2, 2, 535, 539, 7, 32, 2, 2, 536, 538, 5, 90, 46, 2, 537, 536, 3, 2, 2, 2, 538, 541, 3, 2, 2, 2, 539, 537, 3, 2, 2, 2, 539, 540, 3, 2, 2, 2, 540, 542, 3, 2, 2, 2, 541, 539, 3, 2, 2, 2, 542, 543, 7, 33, 2, 2, 543, 89, 3, 2, 2, 2, 544, 545, 5, 92, 47, 2, 545, 547, 7, 39, 2, 2, 546, 548, 5, 52, 27, 2, 547, 546, 3, 2, 2, 2, 547, 548, 3, 2, 2, 2, 548, 91, 3, 2, 2, 2, 549, 550, 7, 8, 2, 2, 550, 553, 5, 20, 11, 2, 551, 553, 7, 4, 2, 2, 552, 549, 3, 2, 2, 2, 552, 551, 3, 2, 2, 2, 553, 93, 3, 2, 2, 2, 554, 563, 7, 17, 2, 2, 555, 564, 5, 96, 49, 2, 556, 557, 5, 208, 105, 2, 557, 558, 5, 96, 49, 2, 558, 564, 3, 2, 2, 2, 559, 560, 5, 56, 29, 2, 560, 561, 5, 208, 105, 2, 561, 562, 5, 96, 49, 2, 562, 564, 3, 2, 2, 2, 563, 555, 3, 2, 2, 2, 563, 556, 3, 2, 2, 2, 563, 559, 3, 2, 2, 2, 564, 565, 3, 2, 2, 2, 565, 569, 7, 32, 2, 2, 566, 568, 5, 98, 50, 2, 567, 566, 3, 2, 2, 2, 568, 571, 3, 2, 2, 2, 569, 567, 3, 2, 2, 2, 569, 570, 3, 2, 2, 2, 570, 572, 3, 2, 2, 2, 571, 569, 3, 2, 2, 2, 572, 573, 7, 33, 2, 2, 573, 95, 3, 2, 2, 2, 574, 575, 7, 29, 2, 2, 575, 577, 7, 43, 2, 2, 576, 574, 3, 2, 2, 2, 576, 577, 3, 2, 2, 2, 577, 578, 3, 2, 2, 2, 578, 579, 5, 158, 80, 2, 579, 580, 7, 40, 2, 2, 580, 581, 7, 30, 2, 2, 581, 582, 7, 22, 2, 2, 582, 583, 7, 31, 2, 2, 583, 97, 3, 2, 2, 2, 584, 585, 5, 100, 51, 2, 585, 587, 7, 39, 2, 2, 586, 588, 5, 52, 27, 2, 587, 586, 3, 2, 2, 2, 587, 588, 3, 2, 2, 2, 588, 99, 3, 2, 2, 2, 589, 590, 7, 8, 2, 2, 590, 593, 5, 102, 52, 2, 591, 593, 7, 4, 2, 2, 592, 589, 3, 2, 2, 2, 592, 591, 3, 2, 2, 2, 593, 101, 3, 2, 2, 2, 594, 597, 5, 120, 61, 2, 595, 597, 7, 28, 2, 2, 596, 594, 3, 2, 2, 2, 596, 595, 3, 2, 2, 2, 597, 605, 3, 2, 2, 2, 598, 601, 7, 37, 2, 2, 599, 602, 5, 120, 61, 2, 600, 602, 7, 28, 2, 2, 601, 599, 3, 2, 2, 2, 601, 600, 3, 2, 2, 2, 602, 604, 3, 2, 2, 2, 603, 598, 3, 2, 2, 2, 604, 607, 3, 2, 2, 2, 605, 603, 3, 2, 2, 2, 605, 606, 3, 2, 2, 2, 606, 103, 3, 2, 2, 2, 607, 605, 3, 2, 2, 2, 608, 609, 7, 7, 2, 2, 609, 613, 7, 32, 2, 2, 610, 612, 5, 106, 54, 2, 611, 610, 3, 2, 2, 2, 612, 615, 3, 2, 2, 2, 613, 611, 3, 2, 2, 2, 613, 614, 3, 2, 2, 2, 614, 616, 3, 2, 2, 2, 615, 613, 3, 2, 2, 2, 616, 617, 7, 33, 2, 2, 617, 105, 3, 2, 2, 2, 618, 619, 5, 108, 55, 2, 619, 621, 7, 39, 2, 2, 620, 622, 5, 52, 27, 2, 621, 620, 3, 2, 2, 2, 621, 622, 3, 2, 2, 2, 622, 107, 3, 2, 2, 2, 623, 626, 7, 8, 2, 2, 624, 627, 5, 60, 31, 2, 625, 627, 5, 110, 56, 2, 626, 624, 3, 2, 2, 2, 626, 625, 3, 2, 2, 2, 627, 630, 3, 2, 2, 2, 628, 630, 7, 4, 2, 2, 629, 623, 3, 2, 2, 2, 629, 628, 3, 2, 2, 2, 630, 109, 3, 2, 2, 2, 631, 632, 5, 20, 11, 2, 632, 633, 7, 36, 2, 2, 633, 638, 3, 2, 2, 2, 634, 635, 5, 18, 10, 2, 635, 636, 7, 43, 2, 2, 636, 638, 3, 2, 2, 2, 637, 631, 3, 2, 2, 2, 637, 634, 3, 2, 2, 2, 637, 638, 3, 2, 2, 2, 638, 639, 3, 2, 2, 2, 639, 640, 5, 156, 79, 2, 640, 111, 3, 2, 2, 2, 641, 649, 7, 24, 2, 2, 642, 644, 5, 156, 79, 2, 643, 642, 3, 2, 2, 2, 643, 644, 3, 2, 2, 2, 644, 650, 3, 2, 2, 2, 645, 650, 5, 114, 58, 2, 646, 648, 5, 116, 59, 2, 647, 646, 3, 2, 2, 2, 647, 648, 3, 2, 2, 2, 648, 650, 3, 2, 2, 2, 649, 643, 3, 2, 2, 2, 649, 645, 3, 2, 2, 2, 649, 647, 3, 2, 2, 2, 650, 651, 3, 2, 2, 2, 651, 652, 5, 50, 26, 2, 652, 113, 3, 2, 2, 2, 653, 655, 5, 56, 29, 2, 654, 653, 3, 2, 2, 2, 654, 655, 3, 2, 2, 2, 655, 656, 3, 2, 2, 2, 656, 658, 5, 208, 105, 2, 657, 659, 5, 156, 79, 2, 658, 657, 3, 2, 2, 2, 658, 659, 3, 2, 2, 2, 659, 660, 3, 2, 2, 2, 660, 662, 5, 208, 105, 2, 661, 663, 5, 56, 29, 2, 662, 661, 3, 2, 2, 2, 662, 663, 3, 2, 2, 2, 663, 115, 3, 2, 2, 2, 664, 665, 5, 20, 11, 2, 665, 666, 7, 36, 2, 2, 666, 671, 3, 2, 2, 2, 667, 668, 5, 18, 10, 2, 668, 669, 7, 43, 2, 2, 669, 671, 3, 2, 2, 2, 670, 664, 3, 2, 2, 2, 670, 667, 3, 2, 2, 2, 670, 671, 3, 2, 2, 2, 671, 672, 3, 2, 2, 2, 672, 673, 7, 21, 2, 2, 673, 674, 5, 156, 79, 2, 674, 117, 3, 2, 2, 2, 675, 676, 7, 10, 2, 2, 676, 677, 5, 156, 79, 2, 677, 119, 3, 2, 2, 2, 678, 680, 5, 124, 63, 2, 679, 681, 5, 122, 62, 2, 680, 679, 3, 2, 2, 2, 680, 681, 3, 2, 2, 2, 681, 688, 3, 2, 2, 2, 682, 688, 5, 126, 64, 2, 683, 684, 7, 30, 2, 2, 684, 685, 5, 120, 61, 2, 685, 686, 7, 31, 2, 2, 686, 688, 3, 2, 2, 2, 687, 678, 3, 2, 2, 2, 687, 682, 3, 2, 2, 2, 687, 683, 3, 2, 2, 2, 688, 121, 3, 2, 2, 2, 689, 690, 7, 34, 2, 2, 690, 692, 5, 102, 52, 2, 691, 693, 7, 37, 2, 2, 692, 691, 3, 2, 2, 2, 692, 693, 3, 2, 2, 2, 693, 694, 3, 2, 2, 2, 694, 695, 7, 35, 2, 2, 695, 123, 3, 2, 2, 2, 696, 699, 5, 172, 87, 2, 697, 699, 7, 29, 2, 2, 698, 696, 3, 2, 2, 2, 698, 697, 3, 2, 2, 2, 699, 125, 3, 2, 2, 2, 700, 709, 5, 128, 65, 2, 701, 709, 5, 188, 95, 2, 702, 709, 5, 134, 68, 2, 703, 709, 5, 146, 74, 2, 704, 709, 5, 136, 69, 2, 705, 709, 5, 138, 70, 2, 706, 709, 5, 140, 71, 2, 707, 709, 5, 142, 72, 2, 708, 700, 3, 2, 2, 2, 708, 701, 3, 2, 2, 2, 708, 702, 3, 2, 2, 2, 708, 703, 3, 2, 2, 2, 708, 704, 3, 2, 2, 2, 708, 705, 3, 2, 2, 2, 708, 706, 3, 2, 2, 2, 708, 707, 3, 2, 2, 2, 709, 127, 3, 2, 2, 2, 710, 711, 7, 34, 2, 2, 711, 712, 5, 130, 66, 2, 712, 713, 7, 35, 2, 2, 713, 714, 5, 132, 67, 2, 714, 129, 3, 2, 2, 2, 715, 716, 5, 156, 79, 2, 716, 131, 3, 2, 2, 2, 717, 718, 5, 120, 61, 2, 718, 133, 3, 2, 2, 2, 719, 720, 7, 64, 2, 2, 720, 721, 5, 120, 61, 2, 721, 135, 3, 2, 2, 2, 722, 723, 7, 6, 2, 2, 723, 732, 7, 32, 2, 2, 724, 727, 5, 144, 73, 2, 725, 727, 5, 36, 19, 2, 726, 724, 3, 2, 2, 2, 726, 725, 3, 2, 2, 2, 727, 728, 3, 2, 2, 2, 728, 729, 5, 208, 105, 2, 729, 731, 3, 2, 2, 2, 730, 726, 3, 2, 2, 2, 731, 734, 3, 2, 2, 2, 732, 730, 3, 2, 2, 2, 732, 733, 3, 2, 2, 2, 733, 735, 3, 2, 2, 2, 734, 732, 3, 2, 2, 2, 735, 736, 7, 33, 2, 2, 736, 137, 3, 2, 2, 2, 737, 738, 7, 34, 2, 2, 738, 739, 7, 35, 2, 2, 739, 740, 5, 132, 67, 2, 740, 139, 3, 2, 2, 2, 741, 742, 7, 11, 2, 2, 742, 743, 7, 34, 2, 2, 743, 744, 5, 120, 61, 2, 744, 745, 7, 35, 2, 2, 745, 746, 5, 132, 67, 2, 746, 141, 3, 2, 2, 2, 747, 753, 7, 13, 2, 2, 748, 749, 7, 13, 2, 2, 749, 753, 7, 66, 2, 2, 750, 751, 7, 66, 2, 2, 751, 753, 7, 13, 2, 2, 752, 747, 3, 2, 2, 2, 752, 748, 3, 2, 2, 2, 752, 750, 3, 2, 2, 2, 753, 754, 3, 2, 2, 2, 754, 755, 5, 132, 67, 2, 755, 143, 3, 2, 2, 2, 756, 757, 7, 29, 2, 2, 757, 758, 5, 152, 77, 2, 758, 759, 5, 150, 76, 2, 759, 763, 3, 2, 2, 2, 760, 761, 7, 29, 2, 2, 761, 763, 5, 152, 77, 2, 762, 756, 3, 2, 2, 2, 762, 760, 3, 2, 2, 2, 763, 145, 3, 2, 2, 2, 764, 765, 7, 5, 2, 2, 765, 766, 5, 148, 75, 2, 766, 147, 3, 2, 2, 2, 767, 769, 5, 152, 77, 2, 768, 770, 5, 150, 76, 2, 769, 768, 3, 2, 2, 2, 769, 770, 3, 2, 2, 2, 770, 149, 3, 2, 2, 2, 771, 774, 5, 152, 77, 2, 772, 774, 5, 120, 61, 2, 773, 771, 3, 2, 2, 2, 773, 772, 3, 2, 2, 2, 774, 151, 3, 2, 2, 2, 775, 787, 7, 30, 2, 2, 776, 781, 5, 154, 78, 2, 777, 778, 7, 37, 2, 2, 778, 780, 5, 154, 78, 2, 779, 777, 3, 2, 2, 2, 780, 783, 3, 2, 2, 2, 781, 779, 3, 2, 2, 2, 781, 782, 3, 2, 2, 2, 782, 785, 3, 2, 2, 2, 783, 781, 3, 2, 2, 2, 784, 786, 7, 37, 2, 2, 785, 784, 3, 2, 2, 2, 785, 786, 3, 2, 2, 2, 786, 788, 3, 2, 2, 2, 787, 776, 3, 2, 2, 2, 787, 788, 3, 2, 2, 2, 788, 789, 3, 2, 2, 2, 789, 790, 7, 31, 2, 2, 790, 153, 3, 2, 2, 2, 791, 793, 5, 18, 10, 2, 792, 791, 3, 2, 2, 2, 792, 793, 3, 2, 2, 2, 793, 795, 3, 2, 2, 2, 794, 796, 7, 44, 2, 2, 795, 794, 3, 2, 2, 2, 795, 796, 3, 2, 2, 2, 796, 797, 3, 2, 2, 2, 797, 798, 5, 120, 61, 2, 798, 155, 3, 2, 2, 2, 799, 800, 8, 79, 1, 2, 800, 804, 5, 158, 80, 2, 801, 802, 9, 6, 2, 2, 802, 804, 5, 156, 79, 8, 803, 799, 3, 2, 2, 2, 803, 801, 3, 2, 2, 2, 804, 822, 3, 2, 2, 2, 805, 806, 12, 7, 2, 2, 806, 807, 9, 7, 2, 2, 807, 821, 5, 156, 79, 8, 808, 809, 12, 6, 2, 2, 809, 810, 9, 8, 2, 2, 810, 821, 5, 156, 79, 7, 811, 812, 12, 5, 2, 2, 812, 813, 9, 9, 2, 2, 813, 821, 5, 156, 79, 6, 814, 815, 12, 4, 2, 2, 815, 816, 7, 46, 2, 2, 816, 821, 5, 156, 79, 5, 817, 818, 12, 3, 2, 2, 818, 819, 7, 45, 2, 2, 819, 821, 5, 156, 79, 4, 820, 805, 3, 2, 2, 2, 820, 808, 3, 2, 2, 2, 820, 811, 3, 2, 2, 2, 820, 814, 3, 2, 2, 2, 820, 817, 3, 2, 2, 2, 821, 824, 3, 2, 2, 2, 822, 820, 3, 2, 2, 2, 822, 823, 3, 2, 2, 2, 823, 157, 3, 2, 2, 2, 824, 822, 3, 2, 2, 2, 825, 826, 8, 80, 1, 2, 826, 830, 5, 162, 82, 2, 827, 830, 5, 160, 81, 2, 828, 830, 5, 206, 104, 2, 829, 825, 3, 2, 2, 2, 829, 827, 3, 2, 2, 2, 829, 828, 3, 2, 2, 2, 830, 842, 3, 2, 2, 2, 831, 838, 12, 3, 2, 2, 832, 833, 7, 40, 2, 2, 833, 839, 7, 29, 2, 2, 834, 839, 5, 198, 100, 2, 835, 839, 5, 200, 101, 2, 836, 839, 5, 202, 102, 2, 837, 839, 5, 204, 103, 2, 838, 832, 3, 2, 2, 2, 838, 834, 3, 2, 2, 2, 838, 835, 3, 2, 2, 2, 838, 836, 3, 2, 2, 2, 838, 837, 3, 2, 2, 2, 839, 841, 3, 2, 2, 2, 840, 831, 3, 2, 2, 2, 841, 844, 3, 2, 2, 2, 842, 840, 3, 2, 2, 2, 842, 843, 3, 2, 2, 2, 843, 159, 3, 2, 2, 2, 844, 842, 3, 2, 2, 2, 845, 846, 5, 120, 61, 2, 846, 847, 7, 30, 2, 2, 847, 849, 5, 156, 79, 2, 848, 850, 7, 37, 2, 2, 849, 848, 3, 2, 2, 2, 849, 850, 3, 2, 2, 2, 850, 851, 3, 2, 2, 2, 851, 852, 7, 31, 2, 2, 852, 161, 3, 2, 2, 2, 853, 863, 5, 164, 83, 2, 854, 856, 5, 170, 86, 2, 855, 857, 5, 122, 62, 2, 856, 855, 3, 2, 2, 2, 856, 857, 3, 2, 2, 2, 857, 863, 3, 2, 2, 2, 858, 859, 7, 30, 2, 2, 859, 860, 5, 156, 79, 2, 860, 861, 7, 31, 2, 2, 861, 863, 3, 2, 2, 2, 862, 853, 3, 2, 2, 2, 862, 854, 3, 2, 2, 2, 862, 858, 3, 2, 2, 2, 863, 163, 3, 2, 2, 2, 864, 868, 5, 166, 84, 2, 865, 868, 5, 174, 88, 2, 866, 868, 5, 196, 99, 2, 867, 864, 3, 2, 2, 2, 867, 865, 3, 2, 2, 2, 867, 866, 3, 2, 2, 2, 868, 165, 3, 2, 2, 2, 869, 874, 7, 28, 2, 2, 870, 874, 5, 168, 85, 2, 871, 874, 5, 192, 97, 2, 872, 874, 7, 71, 2, 2, 873, 869, 3, 2, 2, 2, 873, 870, 3, 2, 2, 2, 873, 871, 3, 2, 2, 2, 873, 872, 3, 2, 2, 2, 874, 167, 3, 2, 2, 2, 875, 876, 9, 10, 2, 2, 876, 169, 3, 2, 2, 2, 877, 878, 7, 29, 2, 2, 878, 171, 3, 2, 2, 2, 879, 880, 7, 29, 2, 2, 880, 881, 7, 40, 2, 2, 881, 882, 7, 29, 2, 2, 882, 173, 3, 2, 2, 2, 883, 884, 5, 176, 89, 2, 884, 885, 5, 178, 90, 2, 885, 175, 3, 2, 2, 2, 886, 899, 5, 188, 95, 2, 887, 899, 5, 128, 65, 2, 888, 889, 7, 34, 2, 2, 889, 890, 7, 44, 2, 2, 890, 891, 7, 35, 2, 2, 891, 899, 5, 132, 67, 2, 892, 899, 5, 138, 70, 2, 893, 899, 5, 140, 71, 2, 894, 896, 5, 124, 63, 2, 895, 897, 5, 122, 62, 2, 896, 895, 3, 2, 2, 2, 896, 897, 3, 2, 2, 2, 897, 899, 3, 2, 2, 2, 898, 886, 3, 2, 2, 2, 898, 887, 3, 2, 2, 2, 898, 888, 3, 2, 2, 2, 898, 892, 3, 2, 2, 2, 898, 893, 3, 2, 2, 2, 898, 894, 3, 2, 2, 2, 899, 177, 3, 2, 2, 2, 900, 905, 7, 32, 2, 2, 901, 903, 5, 180, 91, 2, 902, 904, 7, 37, 2, 2, 903, 902, 3, 2, 2, 2, 903, 904, 3, 2, 2, 2, 904, 906, 3, 2, 2, 2, 905, 901, 3, 2, 2, 2, 905, 906, 3, 2, 2, 2, 906, 907, 3, 2, 2, 2, 907, 908, 7, 33, 2, 2, 908, 179, 3, 2, 2, 2, 909, 914, 5, 182, 92, 2, 910, 911, 7, 37, 2, 2, 911, 913, 5, 182, 92, 2, 912, 910, 3, 2, 2, 2, 913, 916, 3, 2, 2, 2, 914, 912, 3, 2, 2, 2, 914, 915, 3, 2, 2, 2, 915, 181, 3, 2, 2, 2, 916, 914, 3, 2, 2, 2, 917, 918, 5, 184, 93, 2, 918, 919, 7, 39, 2, 2, 919, 921, 3, 2, 2, 2, 920, 917, 3, 2, 2, 2, 920, 921, 3, 2, 2, 2, 921, 922, 3, 2, 2, 2, 922, 923, 5, 186, 94, 2, 923, 183, 3, 2, 2, 2, 924, 927, 5, 156, 79, 2, 925, 927, 5, 178, 90, 2, 926, 924, 3, 2, 2, 2, 926, 925, 3, 2, 2, 2, 927, 185, 3, 2, 2, 2, 928, 931, 5, 156, 79, 2, 929, 931, 5, 178, 90, 2, 930, 928, 3, 2, 2, 2, 930, 929, 3, 2, 2, 2, 931, 187, 3, 2, 2, 2, 932, 933, 7, 12, 2, 2, 933, 939, 7, 32, 2, 2, 934, 935, 5, 190, 96, 2, 935, 936, 5, 208, 105, 2, 936, 938, 3, 2, 2, 2, 937, 934, 3, 2, 2, 2, 938, 941, 3, 2, 2, 2, 939, 937, 3, 2, 2, 2, 939, 940, 3, 2, 2, 2, 940, 942, 3, 2, 2, 2, 941, 939, 3, 2, 2, 2, 942, 943, 7, 33, 2, 2, 943, 189, 3, 2, 2, 2, 944, 945, 5, 18, 10, 2, 945, 946, 5, 120, 61, 2, 946, 949, 3, 2, 2, 2, 947, 949, 5, 194, 98, 2, 948, 944, 3, 2, 2, 2, 948, 947, 3, 2, 2, 2, 949, 951, 3, 2, 2, 2, 950, 952, 5, 192, 97, 2, 951, 950, 3, 2, 2, 2, 951, 952, 3, 2, 2, 2, 952, 191, 3, 2, 2, 2, 953, 954, 9, 11, 2, 2, 954, 193, 3, 2, 2, 2, 955, 957, 7, 64, 2, 2, 956, 955, 3, 2, 2, 2, 956, 957, 3, 2, 2, 2, 957, 958, 3, 2, 2, 2, 958, 960, 5, 124, 63, 2, 959, 961, 5, 122, 62, 2, 960, 959, 3, 2, 2, 2, 960, 961, 3, 2, 2, 2, 961, 195, 3, 2, 2, 2, 962, 963, 7, 5, 2, 2, 963, 964, 5, 148, 75, 2, 964, 965, 5, 50, 26, 2, 965, 197, 3, 2, 2, 2, 966, 967, 7, 34, 2, 2, 967, 968, 5, 156, 79, 2, 968, 969, 7, 35, 2, 2, 969, 199, 3, 2, 2, 2, 970, 986, 7, 34, 2, 2, 971, 973, 5, 156, 79, 2, 972, 971, 3, 2, 2, 2, 972, 973, 3, 2, 2, 2, 973, 974, 3, 2, 2, 2, 974, 976, 7, 39, 2, 2, 975, 977, 5, 156, 79, 2, 976, 975, 3, 2, 2, 2, 976, 977, 3, 2, 2, 2, 977, 987, 3, 2, 2, 2, 978, 980, 5, 156, 79, 2, 979, 978, 3, 2, 2, 2, 979, 980, 3, 2, 2, 2, 980, 981, 3, 2, 2, 2, 981, 982, 7, 39, 2, 2, 982, 983, 5, 156, 79, 2, 983, 984, 7, 39, 2, 2, 984, 985, 5, 156, 79, 2, 985, 987, 3, 2, 2, 2, 986, 972, 3, 2, 2, 2, 986, 979, 3, 2, 2, 2, 987, 988, 3, 2, 2, 2, 988, 989, 7, 35, 2, 2, 989, 201, 3, 2, 2, 2, 990, 991, 7, 40, 2, 2, 991, 992, 7, 30, 2, 2, 992, 993, 5, 120, 61, 2, 993, 994, 7, 31, 2, 2, 994, 203, 3, 2, 2, 2, 995, 1010, 7, 30, 2, 2, 996, 1003, 5, 20, 11, 2, 997, 1000, 5, 120, 61, 2, 998, 999, 7, 37, 2, 2, 999, 1001, 5, 20, 11, 2, 1000, 998, 3, 2, 2, 2, 1000, 1001, 3, 2, 2, 2, 1001, 1003, 3, 2, 2, 2, 1002, 996, 3, 2, 2, 2, 1002, 997, 3, 2, 2, 2, 1003, 1005, 3, 2, 2, 2, 1004, 1006, 7, 44, 2, 2, 1005, 1004, 3, 2, 2, 2, 1005, 1006, 3, 2, 2, 2, 1006, 1008, 3, 2, 2, 2, 1007, 1009, 7, 37, 2, 2, 1008, 1007, 3, 2, 2, 2, 1008, 1009, 3, 2, 2, 2, 1009, 1011, 3, 2, 2, 2, 1010, 1002, 3, 2, 2, 2, 1010, 1011, 3, 2, 2, 2, 1011, 1012, 3, 2, 2, 2, 1012, 1013, 7, 31, 2, 2, 1013, 205, 3, 2, 2, 2, 1014, 1015, 5, 120, 61, 2, 1015, 1016, 7, 40, 2, 2, 1016, 1017, 7, 29, 2, 2, 1017, 207, 3, 2, 2, 2, 1018, 1023, 7, 38, 2, 2, 1019, 1023, 7, 2, 2, 3, 1020, 1023, 7, 91, 2, 2, 1021, 1023, 6, 105, 9, 2, 1022, 1018, 3, 2, 2, 2, 1022, 1019, 3, 2, 2, 2, 1022, 1020, 3, 2, 2, 2, 1022, 1021, 3, 2, 2, 2, 1023, 209, 3, 2, 2, 2, 123, 217, 223, 229, 245, 249, 252, 261, 271, 275, 279, 283, 290, 298, 306, 317, 321, 325, 333, 343, 356, 360, 367, 371, 378, 390, 394, 400, 404, 408, 413, 416, 419, 426, 443, 450, 466, 477, 481, 485, 489, 508, 514, 516, 520, 524, 527, 531, 533, 539, 547, 552, 563, 569, 576, 587, 592, 596, 601, 605, 613, 621, 626, 629, 637, 643, 647, 649, 654, 658, 662, 670, 680, 687, 692, 698, 708, 726, 732, 752, 762, 769, 773, 781, 785, 787, 792, 795, 803, 820, 822, 829, 838, 842, 849, 856, 862, 867, 873, 896, 898, 903, 905, 914, 920, 926, 930, 939, 948, 951, 956, 960, 972, 976, 979, 986, 1000, 1002, 1005, 1008, 1010, 1022] \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.java new file mode 100644 index 000000000..8c200f3d8 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.java @@ -0,0 +1,7752 @@ +package run.mone.antlr.golang;// Generated from GoParser.g4 by ANTLR 4.7.1 + +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; + +import java.util.List; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class GoParser extends GoParserBase { + static { RuntimeMetaData.checkVersion("4.7.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + BREAK=1, DEFAULT=2, FUNC=3, INTERFACE=4, SELECT=5, CASE=6, DEFER=7, GO=8, + MAP=9, STRUCT=10, CHAN=11, ELSE=12, GOTO=13, PACKAGE=14, SWITCH=15, CONST=16, + FALLTHROUGH=17, IF=18, RANGE=19, TYPE=20, CONTINUE=21, FOR=22, IMPORT=23, + RETURN=24, VAR=25, NIL_LIT=26, IDENTIFIER=27, L_PAREN=28, R_PAREN=29, + L_CURLY=30, R_CURLY=31, L_BRACKET=32, R_BRACKET=33, ASSIGN=34, COMMA=35, + SEMI=36, COLON=37, DOT=38, PLUS_PLUS=39, MINUS_MINUS=40, DECLARE_ASSIGN=41, + ELLIPSIS=42, LOGICAL_OR=43, LOGICAL_AND=44, EQUALS=45, NOT_EQUALS=46, + LESS=47, LESS_OR_EQUALS=48, GREATER=49, GREATER_OR_EQUALS=50, OR=51, DIV=52, + MOD=53, LSHIFT=54, RSHIFT=55, BIT_CLEAR=56, UNDERLYING=57, EXCLAMATION=58, + PLUS=59, MINUS=60, CARET=61, STAR=62, AMPERSAND=63, RECEIVE=64, DECIMAL_LIT=65, + BINARY_LIT=66, OCTAL_LIT=67, HEX_LIT=68, FLOAT_LIT=69, DECIMAL_FLOAT_LIT=70, + HEX_FLOAT_LIT=71, IMAGINARY_LIT=72, RUNE_LIT=73, BYTE_VALUE=74, OCTAL_BYTE_VALUE=75, + HEX_BYTE_VALUE=76, LITTLE_U_VALUE=77, BIG_U_VALUE=78, RAW_STRING_LIT=79, + INTERPRETED_STRING_LIT=80, WS=81, COMMENT=82, TERMINATOR=83, LINE_COMMENT=84, + NEWLINE=85, WS_NLSEMI=86, COMMENT_NLSEMI=87, LINE_COMMENT_NLSEMI=88, EOS=89, + OTHER=90; + public static final int + RULE_sourceFile = 0, RULE_packageClause = 1, RULE_importDecl = 2, RULE_importSpec = 3, + RULE_importPath = 4, RULE_declaration = 5, RULE_constDecl = 6, RULE_constSpec = 7, + RULE_identifierList = 8, RULE_expressionList = 9, RULE_comment = 10, RULE_typeDecl = 11, + RULE_typeSpec = 12, RULE_aliasDecl = 13, RULE_typeDef = 14, RULE_typeParameters = 15, + RULE_typeParameterDecl = 16, RULE_typeElement = 17, RULE_typeTerm = 18, + RULE_functionDecl = 19, RULE_methodDecl = 20, RULE_receiver = 21, RULE_varDecl = 22, + RULE_varSpec = 23, RULE_block = 24, RULE_statementList = 25, RULE_statement = 26, + RULE_simpleStmt = 27, RULE_expressionStmt = 28, RULE_sendStmt = 29, RULE_incDecStmt = 30, + RULE_assignment = 31, RULE_assign_op = 32, RULE_shortVarDecl = 33, RULE_labeledStmt = 34, + RULE_returnStmt = 35, RULE_breakStmt = 36, RULE_continueStmt = 37, RULE_gotoStmt = 38, + RULE_fallthroughStmt = 39, RULE_deferStmt = 40, RULE_ifStmt = 41, RULE_switchStmt = 42, + RULE_exprSwitchStmt = 43, RULE_exprCaseClause = 44, RULE_exprSwitchCase = 45, + RULE_typeSwitchStmt = 46, RULE_typeSwitchGuard = 47, RULE_typeCaseClause = 48, + RULE_typeSwitchCase = 49, RULE_typeList = 50, RULE_selectStmt = 51, RULE_commClause = 52, + RULE_commCase = 53, RULE_recvStmt = 54, RULE_forStmt = 55, RULE_forClause = 56, + RULE_rangeClause = 57, RULE_goStmt = 58, RULE_type_ = 59, RULE_typeArgs = 60, + RULE_typeName = 61, RULE_typeLit = 62, RULE_arrayType = 63, RULE_arrayLength = 64, + RULE_elementType = 65, RULE_pointerType = 66, RULE_interfaceType = 67, + RULE_sliceType = 68, RULE_mapType = 69, RULE_channelType = 70, RULE_methodSpec = 71, + RULE_functionType = 72, RULE_signature = 73, RULE_result = 74, RULE_parameters = 75, + RULE_parameterDecl = 76, RULE_expression = 77, RULE_primaryExpr = 78, + RULE_conversion = 79, RULE_operand = 80, RULE_literal = 81, RULE_basicLit = 82, + RULE_integer = 83, RULE_operandName = 84, RULE_qualifiedIdent = 85, RULE_compositeLit = 86, + RULE_literalType = 87, RULE_literalValue = 88, RULE_elementList = 89, + RULE_keyedElement = 90, RULE_key = 91, RULE_element = 92, RULE_structType = 93, + RULE_fieldDecl = 94, RULE_string_ = 95, RULE_embeddedField = 96, RULE_functionLit = 97, + RULE_index = 98, RULE_slice_ = 99, RULE_typeAssertion = 100, RULE_arguments = 101, + RULE_methodExpr = 102, RULE_eos = 103; + public static final String[] ruleNames = { + "sourceFile", "packageClause", "importDecl", "importSpec", "importPath", + "declaration", "constDecl", "constSpec", "identifierList", "expressionList", + "comment", "typeDecl", "typeSpec", "aliasDecl", "typeDef", "typeParameters", + "typeParameterDecl", "typeElement", "typeTerm", "functionDecl", "methodDecl", + "receiver", "varDecl", "varSpec", "block", "statementList", "statement", + "simpleStmt", "expressionStmt", "sendStmt", "incDecStmt", "assignment", + "assign_op", "shortVarDecl", "labeledStmt", "returnStmt", "breakStmt", + "continueStmt", "gotoStmt", "fallthroughStmt", "deferStmt", "ifStmt", + "switchStmt", "exprSwitchStmt", "exprCaseClause", "exprSwitchCase", "typeSwitchStmt", + "typeSwitchGuard", "typeCaseClause", "typeSwitchCase", "typeList", "selectStmt", + "commClause", "commCase", "recvStmt", "forStmt", "forClause", "rangeClause", + "goStmt", "type_", "typeArgs", "typeName", "typeLit", "arrayType", "arrayLength", + "elementType", "pointerType", "interfaceType", "sliceType", "mapType", + "channelType", "methodSpec", "functionType", "signature", "result", "parameters", + "parameterDecl", "expression", "primaryExpr", "conversion", "operand", + "literal", "basicLit", "integer", "operandName", "qualifiedIdent", "compositeLit", + "literalType", "literalValue", "elementList", "keyedElement", "key", "element", + "structType", "fieldDecl", "string_", "embeddedField", "functionLit", + "index", "slice_", "typeAssertion", "arguments", "methodExpr", "eos" + }; + + private static final String[] _LITERAL_NAMES = { + null, "'break'", "'default'", "'func'", "'interface'", "'select'", "'case'", + "'defer'", "'go'", "'map'", "'struct'", "'chan'", "'else'", "'goto'", + "'package'", "'switch'", "'const'", "'fallthrough'", "'if'", "'range'", + "'type'", "'continue'", "'for'", "'import'", "'return'", "'var'", "'nil'", + null, "'('", "')'", "'{'", "'}'", "'['", "']'", "'='", "','", "';'", "':'", + "'.'", "'++'", "'--'", "':='", "'...'", "'||'", "'&&'", "'=='", "'!='", + "'<'", "'<='", "'>'", "'>='", "'|'", "'/'", "'%'", "'<<'", "'>>'", "'&^'", + "'~'", "'!'", "'+'", "'-'", "'^'", "'*'", "'&'", "'<-'" + }; + private static final String[] _SYMBOLIC_NAMES = { + null, "BREAK", "DEFAULT", "FUNC", "INTERFACE", "SELECT", "CASE", "DEFER", + "GO", "MAP", "STRUCT", "CHAN", "ELSE", "GOTO", "PACKAGE", "SWITCH", "CONST", + "FALLTHROUGH", "IF", "RANGE", "TYPE", "CONTINUE", "FOR", "IMPORT", "RETURN", + "VAR", "NIL_LIT", "IDENTIFIER", "L_PAREN", "R_PAREN", "L_CURLY", "R_CURLY", + "L_BRACKET", "R_BRACKET", "ASSIGN", "COMMA", "SEMI", "COLON", "DOT", "PLUS_PLUS", + "MINUS_MINUS", "DECLARE_ASSIGN", "ELLIPSIS", "LOGICAL_OR", "LOGICAL_AND", + "EQUALS", "NOT_EQUALS", "LESS", "LESS_OR_EQUALS", "GREATER", "GREATER_OR_EQUALS", + "OR", "DIV", "MOD", "LSHIFT", "RSHIFT", "BIT_CLEAR", "UNDERLYING", "EXCLAMATION", + "PLUS", "MINUS", "CARET", "STAR", "AMPERSAND", "RECEIVE", "DECIMAL_LIT", + "BINARY_LIT", "OCTAL_LIT", "HEX_LIT", "FLOAT_LIT", "DECIMAL_FLOAT_LIT", + "HEX_FLOAT_LIT", "IMAGINARY_LIT", "RUNE_LIT", "BYTE_VALUE", "OCTAL_BYTE_VALUE", + "HEX_BYTE_VALUE", "LITTLE_U_VALUE", "BIG_U_VALUE", "RAW_STRING_LIT", "INTERPRETED_STRING_LIT", + "WS", "COMMENT", "TERMINATOR", "LINE_COMMENT", "NEWLINE", "WS_NLSEMI", + "COMMENT_NLSEMI", "LINE_COMMENT_NLSEMI", "EOS", "OTHER" + }; + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "GoParser.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public GoParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + public static class SourceFileContext extends ParserRuleContext { + public PackageClauseContext packageClause() { + return getRuleContext(PackageClauseContext.class,0); + } + public List eos() { + return getRuleContexts(EosContext.class); + } + public EosContext eos(int i) { + return getRuleContext(EosContext.class,i); + } + public TerminalNode EOF() { return getToken(GoParser.EOF, 0); } + public List importDecl() { + return getRuleContexts(ImportDeclContext.class); + } + public ImportDeclContext importDecl(int i) { + return getRuleContext(ImportDeclContext.class,i); + } + public List functionDecl() { + return getRuleContexts(FunctionDeclContext.class); + } + public FunctionDeclContext functionDecl(int i) { + return getRuleContext(FunctionDeclContext.class,i); + } + public List methodDecl() { + return getRuleContexts(MethodDeclContext.class); + } + public MethodDeclContext methodDecl(int i) { + return getRuleContext(MethodDeclContext.class,i); + } + public List declaration() { + return getRuleContexts(DeclarationContext.class); + } + public DeclarationContext declaration(int i) { + return getRuleContext(DeclarationContext.class,i); + } + public SourceFileContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_sourceFile; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterSourceFile(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitSourceFile(this); + } + } + + public final SourceFileContext sourceFile() throws RecognitionException { + SourceFileContext _localctx = new SourceFileContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_sourceFile); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(208); + packageClause(); + setState(209); + eos(); + setState(215); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==IMPORT) { + { + { + setState(210); + importDecl(); + setState(211); + eos(); + } + } + setState(217); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(227); + _errHandler.sync(this); + _la = _input.LA(1); + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNC) | (1L << CONST) | (1L << TYPE) | (1L << VAR))) != 0) || _la==COMMENT || _la==LINE_COMMENT) { + { + { + setState(221); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) { + case 1: + { + setState(218); + functionDecl(); + } + break; + case 2: + { + setState(219); + methodDecl(); + } + break; + case 3: + { + setState(220); + declaration(); + } + break; + } + setState(223); + eos(); + } + } + setState(229); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(230); + match(EOF); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class PackageClauseContext extends ParserRuleContext { + public Token packageName; + public TerminalNode PACKAGE() { return getToken(GoParser.PACKAGE, 0); } + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public PackageClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_packageClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterPackageClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitPackageClause(this); + } + } + + public final PackageClauseContext packageClause() throws RecognitionException { + PackageClauseContext _localctx = new PackageClauseContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_packageClause); + try { + enterOuterAlt(_localctx, 1); + { + setState(232); + match(PACKAGE); + setState(233); + ((PackageClauseContext)_localctx).packageName = match(IDENTIFIER); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ImportDeclContext extends ParserRuleContext { + public TerminalNode IMPORT() { return getToken(GoParser.IMPORT, 0); } + public List importSpec() { + return getRuleContexts(ImportSpecContext.class); + } + public ImportSpecContext importSpec(int i) { + return getRuleContext(ImportSpecContext.class,i); + } + public TerminalNode L_PAREN() { return getToken(GoParser.L_PAREN, 0); } + public TerminalNode R_PAREN() { return getToken(GoParser.R_PAREN, 0); } + public List eos() { + return getRuleContexts(EosContext.class); + } + public EosContext eos(int i) { + return getRuleContext(EosContext.class,i); + } + public ImportDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_importDecl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterImportDecl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitImportDecl(this); + } + } + + public final ImportDeclContext importDecl() throws RecognitionException { + ImportDeclContext _localctx = new ImportDeclContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_importDecl); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(235); + match(IMPORT); + setState(247); + _errHandler.sync(this); + switch (_input.LA(1)) { + case IDENTIFIER: + case DOT: + case RAW_STRING_LIT: + case INTERPRETED_STRING_LIT: + { + setState(236); + importSpec(); + } + break; + case L_PAREN: + { + setState(237); + match(L_PAREN); + setState(243); + _errHandler.sync(this); + _la = _input.LA(1); + while (((((_la - 27)) & ~0x3f) == 0 && ((1L << (_la - 27)) & ((1L << (IDENTIFIER - 27)) | (1L << (DOT - 27)) | (1L << (RAW_STRING_LIT - 27)) | (1L << (INTERPRETED_STRING_LIT - 27)))) != 0)) { + { + { + setState(238); + importSpec(); + setState(239); + eos(); + } + } + setState(245); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(246); + match(R_PAREN); + } + break; + default: + throw new NoViableAltException(this); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ImportSpecContext extends ParserRuleContext { + public Token alias; + public ImportPathContext importPath() { + return getRuleContext(ImportPathContext.class,0); + } + public TerminalNode DOT() { return getToken(GoParser.DOT, 0); } + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public ImportSpecContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_importSpec; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterImportSpec(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitImportSpec(this); + } + } + + public final ImportSpecContext importSpec() throws RecognitionException { + ImportSpecContext _localctx = new ImportSpecContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_importSpec); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(250); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==IDENTIFIER || _la==DOT) { + { + setState(249); + ((ImportSpecContext)_localctx).alias = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==IDENTIFIER || _la==DOT) ) { + ((ImportSpecContext)_localctx).alias = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + + setState(252); + importPath(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ImportPathContext extends ParserRuleContext { + public String_Context string_() { + return getRuleContext(String_Context.class,0); + } + public ImportPathContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_importPath; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterImportPath(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitImportPath(this); + } + } + + public final ImportPathContext importPath() throws RecognitionException { + ImportPathContext _localctx = new ImportPathContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_importPath); + try { + enterOuterAlt(_localctx, 1); + { + setState(254); + string_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class DeclarationContext extends ParserRuleContext { + public ConstDeclContext constDecl() { + return getRuleContext(ConstDeclContext.class,0); + } + public TypeDeclContext typeDecl() { + return getRuleContext(TypeDeclContext.class,0); + } + public VarDeclContext varDecl() { + return getRuleContext(VarDeclContext.class,0); + } + public DeclarationContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_declaration; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterDeclaration(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitDeclaration(this); + } + } + + public final DeclarationContext declaration() throws RecognitionException { + DeclarationContext _localctx = new DeclarationContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_declaration); + try { + setState(259); + _errHandler.sync(this); + switch (_input.LA(1)) { + case CONST: + enterOuterAlt(_localctx, 1); + { + setState(256); + constDecl(); + } + break; + case TYPE: + case COMMENT: + case LINE_COMMENT: + enterOuterAlt(_localctx, 2); + { + setState(257); + typeDecl(); + } + break; + case VAR: + enterOuterAlt(_localctx, 3); + { + setState(258); + varDecl(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ConstDeclContext extends ParserRuleContext { + public TerminalNode CONST() { return getToken(GoParser.CONST, 0); } + public List constSpec() { + return getRuleContexts(ConstSpecContext.class); + } + public ConstSpecContext constSpec(int i) { + return getRuleContext(ConstSpecContext.class,i); + } + public TerminalNode L_PAREN() { return getToken(GoParser.L_PAREN, 0); } + public TerminalNode R_PAREN() { return getToken(GoParser.R_PAREN, 0); } + public List eos() { + return getRuleContexts(EosContext.class); + } + public EosContext eos(int i) { + return getRuleContext(EosContext.class,i); + } + public ConstDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_constDecl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterConstDecl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitConstDecl(this); + } + } + + public final ConstDeclContext constDecl() throws RecognitionException { + ConstDeclContext _localctx = new ConstDeclContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_constDecl); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(261); + match(CONST); + setState(273); + _errHandler.sync(this); + switch (_input.LA(1)) { + case IDENTIFIER: + { + setState(262); + constSpec(); + } + break; + case L_PAREN: + { + setState(263); + match(L_PAREN); + setState(269); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==IDENTIFIER) { + { + { + setState(264); + constSpec(); + setState(265); + eos(); + } + } + setState(271); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(272); + match(R_PAREN); + } + break; + default: + throw new NoViableAltException(this); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ConstSpecContext extends ParserRuleContext { + public IdentifierListContext identifierList() { + return getRuleContext(IdentifierListContext.class,0); + } + public TerminalNode ASSIGN() { return getToken(GoParser.ASSIGN, 0); } + public ExpressionListContext expressionList() { + return getRuleContext(ExpressionListContext.class,0); + } + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public ConstSpecContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_constSpec; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterConstSpec(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitConstSpec(this); + } + } + + public final ConstSpecContext constSpec() throws RecognitionException { + ConstSpecContext _localctx = new ConstSpecContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_constSpec); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(275); + identifierList(); + setState(281); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) { + case 1: + { + setState(277); + _errHandler.sync(this); + _la = _input.LA(1); + if (((((_la - 3)) & ~0x3f) == 0 && ((1L << (_la - 3)) & ((1L << (FUNC - 3)) | (1L << (INTERFACE - 3)) | (1L << (MAP - 3)) | (1L << (STRUCT - 3)) | (1L << (CHAN - 3)) | (1L << (IDENTIFIER - 3)) | (1L << (L_PAREN - 3)) | (1L << (L_BRACKET - 3)) | (1L << (STAR - 3)) | (1L << (RECEIVE - 3)))) != 0)) { + { + setState(276); + type_(); + } + } + + setState(279); + match(ASSIGN); + setState(280); + expressionList(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class IdentifierListContext extends ParserRuleContext { + public List IDENTIFIER() { return getTokens(GoParser.IDENTIFIER); } + public TerminalNode IDENTIFIER(int i) { + return getToken(GoParser.IDENTIFIER, i); + } + public List COMMA() { return getTokens(GoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(GoParser.COMMA, i); + } + public IdentifierListContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_identifierList; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterIdentifierList(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitIdentifierList(this); + } + } + + public final IdentifierListContext identifierList() throws RecognitionException { + IdentifierListContext _localctx = new IdentifierListContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_identifierList); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(283); + match(IDENTIFIER); + setState(288); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,11,_ctx); + while ( _alt!=2 && _alt!= ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(284); + match(COMMA); + setState(285); + match(IDENTIFIER); + } + } + } + setState(290); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,11,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ExpressionListContext extends ParserRuleContext { + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public List COMMA() { return getTokens(GoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(GoParser.COMMA, i); + } + public ExpressionListContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_expressionList; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterExpressionList(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitExpressionList(this); + } + } + + public final ExpressionListContext expressionList() throws RecognitionException { + ExpressionListContext _localctx = new ExpressionListContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_expressionList); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(291); + expression(0); + setState(296); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,12,_ctx); + while ( _alt!=2 && _alt!= ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(292); + match(COMMA); + setState(293); + expression(0); + } + } + } + setState(298); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,12,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class CommentContext extends ParserRuleContext { + public TerminalNode COMMENT() { return getToken(GoParser.COMMENT, 0); } + public TerminalNode LINE_COMMENT() { return getToken(GoParser.LINE_COMMENT, 0); } + public CommentContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_comment; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterComment(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitComment(this); + } + } + + public final CommentContext comment() throws RecognitionException { + CommentContext _localctx = new CommentContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_comment); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(299); + _la = _input.LA(1); + if ( !(_la==COMMENT || _la==LINE_COMMENT) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeDeclContext extends ParserRuleContext { + public TerminalNode TYPE() { return getToken(GoParser.TYPE, 0); } + public List typeSpec() { + return getRuleContexts(TypeSpecContext.class); + } + public TypeSpecContext typeSpec(int i) { + return getRuleContext(TypeSpecContext.class,i); + } + public TerminalNode L_PAREN() { return getToken(GoParser.L_PAREN, 0); } + public TerminalNode R_PAREN() { return getToken(GoParser.R_PAREN, 0); } + public List comment() { + return getRuleContexts(CommentContext.class); + } + public CommentContext comment(int i) { + return getRuleContext(CommentContext.class,i); + } + public List eos() { + return getRuleContexts(EosContext.class); + } + public EosContext eos(int i) { + return getRuleContext(EosContext.class,i); + } + public TypeDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeDecl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeDecl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeDecl(this); + } + } + + public final TypeDeclContext typeDecl() throws RecognitionException { + TypeDeclContext _localctx = new TypeDeclContext(_ctx, getState()); + enterRule(_localctx, 22, RULE_typeDecl); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(304); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMENT || _la==LINE_COMMENT) { + { + { + setState(301); + comment(); + } + } + setState(306); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(307); + match(TYPE); + setState(319); + _errHandler.sync(this); + switch (_input.LA(1)) { + case IDENTIFIER: + { + setState(308); + typeSpec(); + } + break; + case L_PAREN: + { + setState(309); + match(L_PAREN); + setState(315); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==IDENTIFIER) { + { + { + setState(310); + typeSpec(); + setState(311); + eos(); + } + } + setState(317); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(318); + match(R_PAREN); + } + break; + default: + throw new NoViableAltException(this); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeSpecContext extends ParserRuleContext { + public AliasDeclContext aliasDecl() { + return getRuleContext(AliasDeclContext.class,0); + } + public TypeDefContext typeDef() { + return getRuleContext(TypeDefContext.class,0); + } + public TypeSpecContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeSpec; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeSpec(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeSpec(this); + } + } + + public final TypeSpecContext typeSpec() throws RecognitionException { + TypeSpecContext _localctx = new TypeSpecContext(_ctx, getState()); + enterRule(_localctx, 24, RULE_typeSpec); + try { + setState(323); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,16,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(321); + aliasDecl(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(322); + typeDef(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class AliasDeclContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public TerminalNode ASSIGN() { return getToken(GoParser.ASSIGN, 0); } + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public AliasDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_aliasDecl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterAliasDecl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitAliasDecl(this); + } + } + + public final AliasDeclContext aliasDecl() throws RecognitionException { + AliasDeclContext _localctx = new AliasDeclContext(_ctx, getState()); + enterRule(_localctx, 26, RULE_aliasDecl); + try { + enterOuterAlt(_localctx, 1); + { + setState(325); + match(IDENTIFIER); + setState(326); + match(ASSIGN); + setState(327); + type_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeDefContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public TypeParametersContext typeParameters() { + return getRuleContext(TypeParametersContext.class,0); + } + public TypeDefContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeDef; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeDef(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeDef(this); + } + } + + public final TypeDefContext typeDef() throws RecognitionException { + TypeDefContext _localctx = new TypeDefContext(_ctx, getState()); + enterRule(_localctx, 28, RULE_typeDef); + try { + enterOuterAlt(_localctx, 1); + { + setState(329); + match(IDENTIFIER); + setState(331); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,17,_ctx) ) { + case 1: + { + setState(330); + typeParameters(); + } + break; + } + setState(333); + type_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeParametersContext extends ParserRuleContext { + public TerminalNode L_BRACKET() { return getToken(GoParser.L_BRACKET, 0); } + public List typeParameterDecl() { + return getRuleContexts(TypeParameterDeclContext.class); + } + public TypeParameterDeclContext typeParameterDecl(int i) { + return getRuleContext(TypeParameterDeclContext.class,i); + } + public TerminalNode R_BRACKET() { return getToken(GoParser.R_BRACKET, 0); } + public List COMMA() { return getTokens(GoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(GoParser.COMMA, i); + } + public TypeParametersContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeParameters; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeParameters(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeParameters(this); + } + } + + public final TypeParametersContext typeParameters() throws RecognitionException { + TypeParametersContext _localctx = new TypeParametersContext(_ctx, getState()); + enterRule(_localctx, 30, RULE_typeParameters); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(335); + match(L_BRACKET); + setState(336); + typeParameterDecl(); + setState(341); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(337); + match(COMMA); + setState(338); + typeParameterDecl(); + } + } + setState(343); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(344); + match(R_BRACKET); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeParameterDeclContext extends ParserRuleContext { + public IdentifierListContext identifierList() { + return getRuleContext(IdentifierListContext.class,0); + } + public TypeElementContext typeElement() { + return getRuleContext(TypeElementContext.class,0); + } + public TypeParameterDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeParameterDecl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeParameterDecl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeParameterDecl(this); + } + } + + public final TypeParameterDeclContext typeParameterDecl() throws RecognitionException { + TypeParameterDeclContext _localctx = new TypeParameterDeclContext(_ctx, getState()); + enterRule(_localctx, 32, RULE_typeParameterDecl); + try { + enterOuterAlt(_localctx, 1); + { + setState(346); + identifierList(); + setState(347); + typeElement(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeElementContext extends ParserRuleContext { + public List typeTerm() { + return getRuleContexts(TypeTermContext.class); + } + public TypeTermContext typeTerm(int i) { + return getRuleContext(TypeTermContext.class,i); + } + public List OR() { return getTokens(GoParser.OR); } + public TerminalNode OR(int i) { + return getToken(GoParser.OR, i); + } + public TypeElementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeElement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeElement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeElement(this); + } + } + + public final TypeElementContext typeElement() throws RecognitionException { + TypeElementContext _localctx = new TypeElementContext(_ctx, getState()); + enterRule(_localctx, 34, RULE_typeElement); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(349); + typeTerm(); + setState(354); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,19,_ctx); + while ( _alt!=2 && _alt!= ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(350); + match(OR); + setState(351); + typeTerm(); + } + } + } + setState(356); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,19,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeTermContext extends ParserRuleContext { + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public TerminalNode UNDERLYING() { return getToken(GoParser.UNDERLYING, 0); } + public TypeTermContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeTerm; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeTerm(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeTerm(this); + } + } + + public final TypeTermContext typeTerm() throws RecognitionException { + TypeTermContext _localctx = new TypeTermContext(_ctx, getState()); + enterRule(_localctx, 36, RULE_typeTerm); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(358); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==UNDERLYING) { + { + setState(357); + match(UNDERLYING); + } + } + + setState(360); + type_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class FunctionDeclContext extends ParserRuleContext { + public TerminalNode FUNC() { return getToken(GoParser.FUNC, 0); } + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public SignatureContext signature() { + return getRuleContext(SignatureContext.class,0); + } + public TypeParametersContext typeParameters() { + return getRuleContext(TypeParametersContext.class,0); + } + public BlockContext block() { + return getRuleContext(BlockContext.class,0); + } + public FunctionDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionDecl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterFunctionDecl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitFunctionDecl(this); + } + } + + public final FunctionDeclContext functionDecl() throws RecognitionException { + FunctionDeclContext _localctx = new FunctionDeclContext(_ctx, getState()); + enterRule(_localctx, 38, RULE_functionDecl); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(362); + match(FUNC); + setState(363); + match(IDENTIFIER); + setState(365); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==L_BRACKET) { + { + setState(364); + typeParameters(); + } + } + + setState(367); + signature(); + setState(369); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,22,_ctx) ) { + case 1: + { + setState(368); + block(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class MethodDeclContext extends ParserRuleContext { + public TerminalNode FUNC() { return getToken(GoParser.FUNC, 0); } + public ReceiverContext receiver() { + return getRuleContext(ReceiverContext.class,0); + } + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public SignatureContext signature() { + return getRuleContext(SignatureContext.class,0); + } + public BlockContext block() { + return getRuleContext(BlockContext.class,0); + } + public MethodDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_methodDecl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterMethodDecl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitMethodDecl(this); + } + } + + public final MethodDeclContext methodDecl() throws RecognitionException { + MethodDeclContext _localctx = new MethodDeclContext(_ctx, getState()); + enterRule(_localctx, 40, RULE_methodDecl); + try { + enterOuterAlt(_localctx, 1); + { + setState(371); + match(FUNC); + setState(372); + receiver(); + setState(373); + match(IDENTIFIER); + setState(374); + signature(); + setState(376); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,23,_ctx) ) { + case 1: + { + setState(375); + block(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ReceiverContext extends ParserRuleContext { + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public ReceiverContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_receiver; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterReceiver(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitReceiver(this); + } + } + + public final ReceiverContext receiver() throws RecognitionException { + ReceiverContext _localctx = new ReceiverContext(_ctx, getState()); + enterRule(_localctx, 42, RULE_receiver); + try { + enterOuterAlt(_localctx, 1); + { + setState(378); + parameters(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class VarDeclContext extends ParserRuleContext { + public TerminalNode VAR() { return getToken(GoParser.VAR, 0); } + public List varSpec() { + return getRuleContexts(VarSpecContext.class); + } + public VarSpecContext varSpec(int i) { + return getRuleContext(VarSpecContext.class,i); + } + public TerminalNode L_PAREN() { return getToken(GoParser.L_PAREN, 0); } + public TerminalNode R_PAREN() { return getToken(GoParser.R_PAREN, 0); } + public List eos() { + return getRuleContexts(EosContext.class); + } + public EosContext eos(int i) { + return getRuleContext(EosContext.class,i); + } + public VarDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_varDecl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterVarDecl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitVarDecl(this); + } + } + + public final VarDeclContext varDecl() throws RecognitionException { + VarDeclContext _localctx = new VarDeclContext(_ctx, getState()); + enterRule(_localctx, 44, RULE_varDecl); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(380); + match(VAR); + setState(392); + _errHandler.sync(this); + switch (_input.LA(1)) { + case IDENTIFIER: + { + setState(381); + varSpec(); + } + break; + case L_PAREN: + { + setState(382); + match(L_PAREN); + setState(388); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==IDENTIFIER) { + { + { + setState(383); + varSpec(); + setState(384); + eos(); + } + } + setState(390); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(391); + match(R_PAREN); + } + break; + default: + throw new NoViableAltException(this); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class VarSpecContext extends ParserRuleContext { + public IdentifierListContext identifierList() { + return getRuleContext(IdentifierListContext.class,0); + } + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public TerminalNode ASSIGN() { return getToken(GoParser.ASSIGN, 0); } + public ExpressionListContext expressionList() { + return getRuleContext(ExpressionListContext.class,0); + } + public VarSpecContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_varSpec; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterVarSpec(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitVarSpec(this); + } + } + + public final VarSpecContext varSpec() throws RecognitionException { + VarSpecContext _localctx = new VarSpecContext(_ctx, getState()); + enterRule(_localctx, 46, RULE_varSpec); + try { + enterOuterAlt(_localctx, 1); + { + setState(394); + identifierList(); + setState(402); + _errHandler.sync(this); + switch (_input.LA(1)) { + case FUNC: + case INTERFACE: + case MAP: + case STRUCT: + case CHAN: + case IDENTIFIER: + case L_PAREN: + case L_BRACKET: + case STAR: + case RECEIVE: + { + setState(395); + type_(); + setState(398); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,26,_ctx) ) { + case 1: + { + setState(396); + match(ASSIGN); + setState(397); + expressionList(); + } + break; + } + } + break; + case ASSIGN: + { + setState(400); + match(ASSIGN); + setState(401); + expressionList(); + } + break; + default: + throw new NoViableAltException(this); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class BlockContext extends ParserRuleContext { + public TerminalNode L_CURLY() { return getToken(GoParser.L_CURLY, 0); } + public TerminalNode R_CURLY() { return getToken(GoParser.R_CURLY, 0); } + public StatementListContext statementList() { + return getRuleContext(StatementListContext.class,0); + } + public BlockContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_block; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterBlock(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitBlock(this); + } + } + + public final BlockContext block() throws RecognitionException { + BlockContext _localctx = new BlockContext(_ctx, getState()); + enterRule(_localctx, 48, RULE_block); + try { + enterOuterAlt(_localctx, 1); + { + setState(404); + match(L_CURLY); + setState(406); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,28,_ctx) ) { + case 1: + { + setState(405); + statementList(); + } + break; + } + setState(408); + match(R_CURLY); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class StatementListContext extends ParserRuleContext { + public List statement() { + return getRuleContexts(StatementContext.class); + } + public StatementContext statement(int i) { + return getRuleContext(StatementContext.class,i); + } + public List eos() { + return getRuleContexts(EosContext.class); + } + public EosContext eos(int i) { + return getRuleContext(EosContext.class,i); + } + public List SEMI() { return getTokens(GoParser.SEMI); } + public TerminalNode SEMI(int i) { + return getToken(GoParser.SEMI, i); + } + public List EOS() { return getTokens(GoParser.EOS); } + public TerminalNode EOS(int i) { + return getToken(GoParser.EOS, i); + } + public StatementListContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_statementList; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterStatementList(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitStatementList(this); + } + } + + public final StatementListContext statementList() throws RecognitionException { + StatementListContext _localctx = new StatementListContext(_ctx, getState()); + enterRule(_localctx, 50, RULE_statementList); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(422); + _errHandler.sync(this); + _alt = 1; + do { + switch (_alt) { + case 1: + { + { + setState(417); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) { + case 1: + { + setState(411); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==SEMI) { + { + setState(410); + match(SEMI); + } + } + + } + break; + case 2: + { + setState(414); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==EOS) { + { + setState(413); + match(EOS); + } + } + + } + break; + case 3: + { + setState(416); + if (!(this.closingBracket())) throw new FailedPredicateException(this, "this.closingBracket()"); + } + break; + } + setState(419); + statement(); + setState(420); + eos(); + } + } + break; + default: + throw new NoViableAltException(this); + } + setState(424); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,32,_ctx); + } while ( _alt!=2 && _alt!= ATN.INVALID_ALT_NUMBER ); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class StatementContext extends ParserRuleContext { + public DeclarationContext declaration() { + return getRuleContext(DeclarationContext.class,0); + } + public LabeledStmtContext labeledStmt() { + return getRuleContext(LabeledStmtContext.class,0); + } + public SimpleStmtContext simpleStmt() { + return getRuleContext(SimpleStmtContext.class,0); + } + public GoStmtContext goStmt() { + return getRuleContext(GoStmtContext.class,0); + } + public ReturnStmtContext returnStmt() { + return getRuleContext(ReturnStmtContext.class,0); + } + public BreakStmtContext breakStmt() { + return getRuleContext(BreakStmtContext.class,0); + } + public ContinueStmtContext continueStmt() { + return getRuleContext(ContinueStmtContext.class,0); + } + public GotoStmtContext gotoStmt() { + return getRuleContext(GotoStmtContext.class,0); + } + public FallthroughStmtContext fallthroughStmt() { + return getRuleContext(FallthroughStmtContext.class,0); + } + public BlockContext block() { + return getRuleContext(BlockContext.class,0); + } + public IfStmtContext ifStmt() { + return getRuleContext(IfStmtContext.class,0); + } + public SwitchStmtContext switchStmt() { + return getRuleContext(SwitchStmtContext.class,0); + } + public SelectStmtContext selectStmt() { + return getRuleContext(SelectStmtContext.class,0); + } + public ForStmtContext forStmt() { + return getRuleContext(ForStmtContext.class,0); + } + public DeferStmtContext deferStmt() { + return getRuleContext(DeferStmtContext.class,0); + } + public StatementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_statement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterStatement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitStatement(this); + } + } + + public final StatementContext statement() throws RecognitionException { + StatementContext _localctx = new StatementContext(_ctx, getState()); + enterRule(_localctx, 52, RULE_statement); + try { + setState(441); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,33,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(426); + declaration(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(427); + labeledStmt(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(428); + simpleStmt(); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(429); + goStmt(); + } + break; + case 5: + enterOuterAlt(_localctx, 5); + { + setState(430); + returnStmt(); + } + break; + case 6: + enterOuterAlt(_localctx, 6); + { + setState(431); + breakStmt(); + } + break; + case 7: + enterOuterAlt(_localctx, 7); + { + setState(432); + continueStmt(); + } + break; + case 8: + enterOuterAlt(_localctx, 8); + { + setState(433); + gotoStmt(); + } + break; + case 9: + enterOuterAlt(_localctx, 9); + { + setState(434); + fallthroughStmt(); + } + break; + case 10: + enterOuterAlt(_localctx, 10); + { + setState(435); + block(); + } + break; + case 11: + enterOuterAlt(_localctx, 11); + { + setState(436); + ifStmt(); + } + break; + case 12: + enterOuterAlt(_localctx, 12); + { + setState(437); + switchStmt(); + } + break; + case 13: + enterOuterAlt(_localctx, 13); + { + setState(438); + selectStmt(); + } + break; + case 14: + enterOuterAlt(_localctx, 14); + { + setState(439); + forStmt(); + } + break; + case 15: + enterOuterAlt(_localctx, 15); + { + setState(440); + deferStmt(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class SimpleStmtContext extends ParserRuleContext { + public SendStmtContext sendStmt() { + return getRuleContext(SendStmtContext.class,0); + } + public IncDecStmtContext incDecStmt() { + return getRuleContext(IncDecStmtContext.class,0); + } + public AssignmentContext assignment() { + return getRuleContext(AssignmentContext.class,0); + } + public ExpressionStmtContext expressionStmt() { + return getRuleContext(ExpressionStmtContext.class,0); + } + public ShortVarDeclContext shortVarDecl() { + return getRuleContext(ShortVarDeclContext.class,0); + } + public SimpleStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_simpleStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterSimpleStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitSimpleStmt(this); + } + } + + public final SimpleStmtContext simpleStmt() throws RecognitionException { + SimpleStmtContext _localctx = new SimpleStmtContext(_ctx, getState()); + enterRule(_localctx, 54, RULE_simpleStmt); + try { + setState(448); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,34,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(443); + sendStmt(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(444); + incDecStmt(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(445); + assignment(); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(446); + expressionStmt(); + } + break; + case 5: + enterOuterAlt(_localctx, 5); + { + setState(447); + shortVarDecl(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ExpressionStmtContext extends ParserRuleContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public ExpressionStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_expressionStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterExpressionStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitExpressionStmt(this); + } + } + + public final ExpressionStmtContext expressionStmt() throws RecognitionException { + ExpressionStmtContext _localctx = new ExpressionStmtContext(_ctx, getState()); + enterRule(_localctx, 56, RULE_expressionStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(450); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class SendStmtContext extends ParserRuleContext { + public ExpressionContext channel; + public TerminalNode RECEIVE() { return getToken(GoParser.RECEIVE, 0); } + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public SendStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_sendStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterSendStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitSendStmt(this); + } + } + + public final SendStmtContext sendStmt() throws RecognitionException { + SendStmtContext _localctx = new SendStmtContext(_ctx, getState()); + enterRule(_localctx, 58, RULE_sendStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(452); + ((SendStmtContext)_localctx).channel = expression(0); + setState(453); + match(RECEIVE); + setState(454); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class IncDecStmtContext extends ParserRuleContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode PLUS_PLUS() { return getToken(GoParser.PLUS_PLUS, 0); } + public TerminalNode MINUS_MINUS() { return getToken(GoParser.MINUS_MINUS, 0); } + public IncDecStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_incDecStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterIncDecStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitIncDecStmt(this); + } + } + + public final IncDecStmtContext incDecStmt() throws RecognitionException { + IncDecStmtContext _localctx = new IncDecStmtContext(_ctx, getState()); + enterRule(_localctx, 60, RULE_incDecStmt); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(456); + expression(0); + setState(457); + _la = _input.LA(1); + if ( !(_la==PLUS_PLUS || _la==MINUS_MINUS) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class AssignmentContext extends ParserRuleContext { + public List expressionList() { + return getRuleContexts(ExpressionListContext.class); + } + public ExpressionListContext expressionList(int i) { + return getRuleContext(ExpressionListContext.class,i); + } + public Assign_opContext assign_op() { + return getRuleContext(Assign_opContext.class,0); + } + public AssignmentContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_assignment; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterAssignment(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitAssignment(this); + } + } + + public final AssignmentContext assignment() throws RecognitionException { + AssignmentContext _localctx = new AssignmentContext(_ctx, getState()); + enterRule(_localctx, 62, RULE_assignment); + try { + enterOuterAlt(_localctx, 1); + { + setState(459); + expressionList(); + setState(460); + assign_op(); + setState(461); + expressionList(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Assign_opContext extends ParserRuleContext { + public TerminalNode ASSIGN() { return getToken(GoParser.ASSIGN, 0); } + public TerminalNode PLUS() { return getToken(GoParser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(GoParser.MINUS, 0); } + public TerminalNode OR() { return getToken(GoParser.OR, 0); } + public TerminalNode CARET() { return getToken(GoParser.CARET, 0); } + public TerminalNode STAR() { return getToken(GoParser.STAR, 0); } + public TerminalNode DIV() { return getToken(GoParser.DIV, 0); } + public TerminalNode MOD() { return getToken(GoParser.MOD, 0); } + public TerminalNode LSHIFT() { return getToken(GoParser.LSHIFT, 0); } + public TerminalNode RSHIFT() { return getToken(GoParser.RSHIFT, 0); } + public TerminalNode AMPERSAND() { return getToken(GoParser.AMPERSAND, 0); } + public TerminalNode BIT_CLEAR() { return getToken(GoParser.BIT_CLEAR, 0); } + public Assign_opContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_assign_op; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterAssign_op(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitAssign_op(this); + } + } + + public final Assign_opContext assign_op() throws RecognitionException { + Assign_opContext _localctx = new Assign_opContext(_ctx, getState()); + enterRule(_localctx, 64, RULE_assign_op); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(464); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << OR) | (1L << DIV) | (1L << MOD) | (1L << LSHIFT) | (1L << RSHIFT) | (1L << BIT_CLEAR) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0)) { + { + setState(463); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << OR) | (1L << DIV) | (1L << MOD) | (1L << LSHIFT) | (1L << RSHIFT) | (1L << BIT_CLEAR) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + + setState(466); + match(ASSIGN); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ShortVarDeclContext extends ParserRuleContext { + public IdentifierListContext identifierList() { + return getRuleContext(IdentifierListContext.class,0); + } + public TerminalNode DECLARE_ASSIGN() { return getToken(GoParser.DECLARE_ASSIGN, 0); } + public ExpressionListContext expressionList() { + return getRuleContext(ExpressionListContext.class,0); + } + public ShortVarDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_shortVarDecl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterShortVarDecl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitShortVarDecl(this); + } + } + + public final ShortVarDeclContext shortVarDecl() throws RecognitionException { + ShortVarDeclContext _localctx = new ShortVarDeclContext(_ctx, getState()); + enterRule(_localctx, 66, RULE_shortVarDecl); + try { + enterOuterAlt(_localctx, 1); + { + setState(468); + identifierList(); + setState(469); + match(DECLARE_ASSIGN); + setState(470); + expressionList(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class LabeledStmtContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public TerminalNode COLON() { return getToken(GoParser.COLON, 0); } + public StatementContext statement() { + return getRuleContext(StatementContext.class,0); + } + public LabeledStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_labeledStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterLabeledStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitLabeledStmt(this); + } + } + + public final LabeledStmtContext labeledStmt() throws RecognitionException { + LabeledStmtContext _localctx = new LabeledStmtContext(_ctx, getState()); + enterRule(_localctx, 68, RULE_labeledStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(472); + match(IDENTIFIER); + setState(473); + match(COLON); + setState(475); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,36,_ctx) ) { + case 1: + { + setState(474); + statement(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ReturnStmtContext extends ParserRuleContext { + public TerminalNode RETURN() { return getToken(GoParser.RETURN, 0); } + public ExpressionListContext expressionList() { + return getRuleContext(ExpressionListContext.class,0); + } + public ReturnStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_returnStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterReturnStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitReturnStmt(this); + } + } + + public final ReturnStmtContext returnStmt() throws RecognitionException { + ReturnStmtContext _localctx = new ReturnStmtContext(_ctx, getState()); + enterRule(_localctx, 70, RULE_returnStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(477); + match(RETURN); + setState(479); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,37,_ctx) ) { + case 1: + { + setState(478); + expressionList(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class BreakStmtContext extends ParserRuleContext { + public TerminalNode BREAK() { return getToken(GoParser.BREAK, 0); } + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public BreakStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_breakStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterBreakStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitBreakStmt(this); + } + } + + public final BreakStmtContext breakStmt() throws RecognitionException { + BreakStmtContext _localctx = new BreakStmtContext(_ctx, getState()); + enterRule(_localctx, 72, RULE_breakStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(481); + match(BREAK); + setState(483); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,38,_ctx) ) { + case 1: + { + setState(482); + match(IDENTIFIER); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ContinueStmtContext extends ParserRuleContext { + public TerminalNode CONTINUE() { return getToken(GoParser.CONTINUE, 0); } + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public ContinueStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_continueStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterContinueStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitContinueStmt(this); + } + } + + public final ContinueStmtContext continueStmt() throws RecognitionException { + ContinueStmtContext _localctx = new ContinueStmtContext(_ctx, getState()); + enterRule(_localctx, 74, RULE_continueStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(485); + match(CONTINUE); + setState(487); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,39,_ctx) ) { + case 1: + { + setState(486); + match(IDENTIFIER); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class GotoStmtContext extends ParserRuleContext { + public TerminalNode GOTO() { return getToken(GoParser.GOTO, 0); } + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public GotoStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_gotoStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterGotoStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitGotoStmt(this); + } + } + + public final GotoStmtContext gotoStmt() throws RecognitionException { + GotoStmtContext _localctx = new GotoStmtContext(_ctx, getState()); + enterRule(_localctx, 76, RULE_gotoStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(489); + match(GOTO); + setState(490); + match(IDENTIFIER); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class FallthroughStmtContext extends ParserRuleContext { + public TerminalNode FALLTHROUGH() { return getToken(GoParser.FALLTHROUGH, 0); } + public FallthroughStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fallthroughStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterFallthroughStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitFallthroughStmt(this); + } + } + + public final FallthroughStmtContext fallthroughStmt() throws RecognitionException { + FallthroughStmtContext _localctx = new FallthroughStmtContext(_ctx, getState()); + enterRule(_localctx, 78, RULE_fallthroughStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(492); + match(FALLTHROUGH); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class DeferStmtContext extends ParserRuleContext { + public TerminalNode DEFER() { return getToken(GoParser.DEFER, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public DeferStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_deferStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterDeferStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitDeferStmt(this); + } + } + + public final DeferStmtContext deferStmt() throws RecognitionException { + DeferStmtContext _localctx = new DeferStmtContext(_ctx, getState()); + enterRule(_localctx, 80, RULE_deferStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(494); + match(DEFER); + setState(495); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class IfStmtContext extends ParserRuleContext { + public TerminalNode IF() { return getToken(GoParser.IF, 0); } + public List block() { + return getRuleContexts(BlockContext.class); + } + public BlockContext block(int i) { + return getRuleContext(BlockContext.class,i); + } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public EosContext eos() { + return getRuleContext(EosContext.class,0); + } + public SimpleStmtContext simpleStmt() { + return getRuleContext(SimpleStmtContext.class,0); + } + public TerminalNode ELSE() { return getToken(GoParser.ELSE, 0); } + public IfStmtContext ifStmt() { + return getRuleContext(IfStmtContext.class,0); + } + public IfStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_ifStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterIfStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitIfStmt(this); + } + } + + public final IfStmtContext ifStmt() throws RecognitionException { + IfStmtContext _localctx = new IfStmtContext(_ctx, getState()); + enterRule(_localctx, 82, RULE_ifStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(497); + match(IF); + setState(506); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,40,_ctx) ) { + case 1: + { + setState(498); + expression(0); + } + break; + case 2: + { + setState(499); + eos(); + setState(500); + expression(0); + } + break; + case 3: + { + setState(502); + simpleStmt(); + setState(503); + eos(); + setState(504); + expression(0); + } + break; + } + setState(508); + block(); + setState(514); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,42,_ctx) ) { + case 1: + { + setState(509); + match(ELSE); + setState(512); + _errHandler.sync(this); + switch (_input.LA(1)) { + case IF: + { + setState(510); + ifStmt(); + } + break; + case L_CURLY: + { + setState(511); + block(); + } + break; + default: + throw new NoViableAltException(this); + } + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class SwitchStmtContext extends ParserRuleContext { + public ExprSwitchStmtContext exprSwitchStmt() { + return getRuleContext(ExprSwitchStmtContext.class,0); + } + public TypeSwitchStmtContext typeSwitchStmt() { + return getRuleContext(TypeSwitchStmtContext.class,0); + } + public SwitchStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_switchStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterSwitchStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitSwitchStmt(this); + } + } + + public final SwitchStmtContext switchStmt() throws RecognitionException { + SwitchStmtContext _localctx = new SwitchStmtContext(_ctx, getState()); + enterRule(_localctx, 84, RULE_switchStmt); + try { + setState(518); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,43,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(516); + exprSwitchStmt(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(517); + typeSwitchStmt(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ExprSwitchStmtContext extends ParserRuleContext { + public TerminalNode SWITCH() { return getToken(GoParser.SWITCH, 0); } + public TerminalNode L_CURLY() { return getToken(GoParser.L_CURLY, 0); } + public TerminalNode R_CURLY() { return getToken(GoParser.R_CURLY, 0); } + public EosContext eos() { + return getRuleContext(EosContext.class,0); + } + public List exprCaseClause() { + return getRuleContexts(ExprCaseClauseContext.class); + } + public ExprCaseClauseContext exprCaseClause(int i) { + return getRuleContext(ExprCaseClauseContext.class,i); + } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public SimpleStmtContext simpleStmt() { + return getRuleContext(SimpleStmtContext.class,0); + } + public ExprSwitchStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_exprSwitchStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterExprSwitchStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitExprSwitchStmt(this); + } + } + + public final ExprSwitchStmtContext exprSwitchStmt() throws RecognitionException { + ExprSwitchStmtContext _localctx = new ExprSwitchStmtContext(_ctx, getState()); + enterRule(_localctx, 86, RULE_exprSwitchStmt); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(520); + match(SWITCH); + setState(531); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,47,_ctx) ) { + case 1: + { + setState(522); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNC) | (1L << INTERFACE) | (1L << MAP) | (1L << STRUCT) | (1L << CHAN) | (1L << NIL_LIT) | (1L << IDENTIFIER) | (1L << L_PAREN) | (1L << L_BRACKET) | (1L << EXCLAMATION) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (RECEIVE - 64)) | (1L << (DECIMAL_LIT - 64)) | (1L << (BINARY_LIT - 64)) | (1L << (OCTAL_LIT - 64)) | (1L << (HEX_LIT - 64)) | (1L << (FLOAT_LIT - 64)) | (1L << (IMAGINARY_LIT - 64)) | (1L << (RUNE_LIT - 64)) | (1L << (RAW_STRING_LIT - 64)) | (1L << (INTERPRETED_STRING_LIT - 64)))) != 0)) { + { + setState(521); + expression(0); + } + } + + } + break; + case 2: + { + setState(525); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,45,_ctx) ) { + case 1: + { + setState(524); + simpleStmt(); + } + break; + } + setState(527); + eos(); + setState(529); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNC) | (1L << INTERFACE) | (1L << MAP) | (1L << STRUCT) | (1L << CHAN) | (1L << NIL_LIT) | (1L << IDENTIFIER) | (1L << L_PAREN) | (1L << L_BRACKET) | (1L << EXCLAMATION) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (RECEIVE - 64)) | (1L << (DECIMAL_LIT - 64)) | (1L << (BINARY_LIT - 64)) | (1L << (OCTAL_LIT - 64)) | (1L << (HEX_LIT - 64)) | (1L << (FLOAT_LIT - 64)) | (1L << (IMAGINARY_LIT - 64)) | (1L << (RUNE_LIT - 64)) | (1L << (RAW_STRING_LIT - 64)) | (1L << (INTERPRETED_STRING_LIT - 64)))) != 0)) { + { + setState(528); + expression(0); + } + } + + } + break; + } + setState(533); + match(L_CURLY); + setState(537); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==DEFAULT || _la==CASE) { + { + { + setState(534); + exprCaseClause(); + } + } + setState(539); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(540); + match(R_CURLY); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ExprCaseClauseContext extends ParserRuleContext { + public ExprSwitchCaseContext exprSwitchCase() { + return getRuleContext(ExprSwitchCaseContext.class,0); + } + public TerminalNode COLON() { return getToken(GoParser.COLON, 0); } + public StatementListContext statementList() { + return getRuleContext(StatementListContext.class,0); + } + public ExprCaseClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_exprCaseClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterExprCaseClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitExprCaseClause(this); + } + } + + public final ExprCaseClauseContext exprCaseClause() throws RecognitionException { + ExprCaseClauseContext _localctx = new ExprCaseClauseContext(_ctx, getState()); + enterRule(_localctx, 88, RULE_exprCaseClause); + try { + enterOuterAlt(_localctx, 1); + { + setState(542); + exprSwitchCase(); + setState(543); + match(COLON); + setState(545); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,49,_ctx) ) { + case 1: + { + setState(544); + statementList(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ExprSwitchCaseContext extends ParserRuleContext { + public TerminalNode CASE() { return getToken(GoParser.CASE, 0); } + public ExpressionListContext expressionList() { + return getRuleContext(ExpressionListContext.class,0); + } + public TerminalNode DEFAULT() { return getToken(GoParser.DEFAULT, 0); } + public ExprSwitchCaseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_exprSwitchCase; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterExprSwitchCase(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitExprSwitchCase(this); + } + } + + public final ExprSwitchCaseContext exprSwitchCase() throws RecognitionException { + ExprSwitchCaseContext _localctx = new ExprSwitchCaseContext(_ctx, getState()); + enterRule(_localctx, 90, RULE_exprSwitchCase); + try { + setState(550); + _errHandler.sync(this); + switch (_input.LA(1)) { + case CASE: + enterOuterAlt(_localctx, 1); + { + setState(547); + match(CASE); + setState(548); + expressionList(); + } + break; + case DEFAULT: + enterOuterAlt(_localctx, 2); + { + setState(549); + match(DEFAULT); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeSwitchStmtContext extends ParserRuleContext { + public TerminalNode SWITCH() { return getToken(GoParser.SWITCH, 0); } + public TerminalNode L_CURLY() { return getToken(GoParser.L_CURLY, 0); } + public TerminalNode R_CURLY() { return getToken(GoParser.R_CURLY, 0); } + public TypeSwitchGuardContext typeSwitchGuard() { + return getRuleContext(TypeSwitchGuardContext.class,0); + } + public EosContext eos() { + return getRuleContext(EosContext.class,0); + } + public SimpleStmtContext simpleStmt() { + return getRuleContext(SimpleStmtContext.class,0); + } + public List typeCaseClause() { + return getRuleContexts(TypeCaseClauseContext.class); + } + public TypeCaseClauseContext typeCaseClause(int i) { + return getRuleContext(TypeCaseClauseContext.class,i); + } + public TypeSwitchStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeSwitchStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeSwitchStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeSwitchStmt(this); + } + } + + public final TypeSwitchStmtContext typeSwitchStmt() throws RecognitionException { + TypeSwitchStmtContext _localctx = new TypeSwitchStmtContext(_ctx, getState()); + enterRule(_localctx, 92, RULE_typeSwitchStmt); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(552); + match(SWITCH); + setState(561); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,51,_ctx) ) { + case 1: + { + setState(553); + typeSwitchGuard(); + } + break; + case 2: + { + setState(554); + eos(); + setState(555); + typeSwitchGuard(); + } + break; + case 3: + { + setState(557); + simpleStmt(); + setState(558); + eos(); + setState(559); + typeSwitchGuard(); + } + break; + } + setState(563); + match(L_CURLY); + setState(567); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==DEFAULT || _la==CASE) { + { + { + setState(564); + typeCaseClause(); + } + } + setState(569); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(570); + match(R_CURLY); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeSwitchGuardContext extends ParserRuleContext { + public PrimaryExprContext primaryExpr() { + return getRuleContext(PrimaryExprContext.class,0); + } + public TerminalNode DOT() { return getToken(GoParser.DOT, 0); } + public TerminalNode L_PAREN() { return getToken(GoParser.L_PAREN, 0); } + public TerminalNode TYPE() { return getToken(GoParser.TYPE, 0); } + public TerminalNode R_PAREN() { return getToken(GoParser.R_PAREN, 0); } + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public TerminalNode DECLARE_ASSIGN() { return getToken(GoParser.DECLARE_ASSIGN, 0); } + public TypeSwitchGuardContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeSwitchGuard; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeSwitchGuard(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeSwitchGuard(this); + } + } + + public final TypeSwitchGuardContext typeSwitchGuard() throws RecognitionException { + TypeSwitchGuardContext _localctx = new TypeSwitchGuardContext(_ctx, getState()); + enterRule(_localctx, 94, RULE_typeSwitchGuard); + try { + enterOuterAlt(_localctx, 1); + { + setState(574); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,53,_ctx) ) { + case 1: + { + setState(572); + match(IDENTIFIER); + setState(573); + match(DECLARE_ASSIGN); + } + break; + } + setState(576); + primaryExpr(0); + setState(577); + match(DOT); + setState(578); + match(L_PAREN); + setState(579); + match(TYPE); + setState(580); + match(R_PAREN); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeCaseClauseContext extends ParserRuleContext { + public TypeSwitchCaseContext typeSwitchCase() { + return getRuleContext(TypeSwitchCaseContext.class,0); + } + public TerminalNode COLON() { return getToken(GoParser.COLON, 0); } + public StatementListContext statementList() { + return getRuleContext(StatementListContext.class,0); + } + public TypeCaseClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeCaseClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeCaseClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeCaseClause(this); + } + } + + public final TypeCaseClauseContext typeCaseClause() throws RecognitionException { + TypeCaseClauseContext _localctx = new TypeCaseClauseContext(_ctx, getState()); + enterRule(_localctx, 96, RULE_typeCaseClause); + try { + enterOuterAlt(_localctx, 1); + { + setState(582); + typeSwitchCase(); + setState(583); + match(COLON); + setState(585); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,54,_ctx) ) { + case 1: + { + setState(584); + statementList(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeSwitchCaseContext extends ParserRuleContext { + public TerminalNode CASE() { return getToken(GoParser.CASE, 0); } + public TypeListContext typeList() { + return getRuleContext(TypeListContext.class,0); + } + public TerminalNode DEFAULT() { return getToken(GoParser.DEFAULT, 0); } + public TypeSwitchCaseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeSwitchCase; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeSwitchCase(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeSwitchCase(this); + } + } + + public final TypeSwitchCaseContext typeSwitchCase() throws RecognitionException { + TypeSwitchCaseContext _localctx = new TypeSwitchCaseContext(_ctx, getState()); + enterRule(_localctx, 98, RULE_typeSwitchCase); + try { + setState(590); + _errHandler.sync(this); + switch (_input.LA(1)) { + case CASE: + enterOuterAlt(_localctx, 1); + { + setState(587); + match(CASE); + setState(588); + typeList(); + } + break; + case DEFAULT: + enterOuterAlt(_localctx, 2); + { + setState(589); + match(DEFAULT); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeListContext extends ParserRuleContext { + public List type_() { + return getRuleContexts(Type_Context.class); + } + public Type_Context type_(int i) { + return getRuleContext(Type_Context.class,i); + } + public List NIL_LIT() { return getTokens(GoParser.NIL_LIT); } + public TerminalNode NIL_LIT(int i) { + return getToken(GoParser.NIL_LIT, i); + } + public List COMMA() { return getTokens(GoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(GoParser.COMMA, i); + } + public TypeListContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeList; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeList(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeList(this); + } + } + + public final TypeListContext typeList() throws RecognitionException { + TypeListContext _localctx = new TypeListContext(_ctx, getState()); + enterRule(_localctx, 100, RULE_typeList); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(594); + _errHandler.sync(this); + switch (_input.LA(1)) { + case FUNC: + case INTERFACE: + case MAP: + case STRUCT: + case CHAN: + case IDENTIFIER: + case L_PAREN: + case L_BRACKET: + case STAR: + case RECEIVE: + { + setState(592); + type_(); + } + break; + case NIL_LIT: + { + setState(593); + match(NIL_LIT); + } + break; + default: + throw new NoViableAltException(this); + } + setState(603); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,58,_ctx); + while ( _alt!=2 && _alt!= ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(596); + match(COMMA); + setState(599); + _errHandler.sync(this); + switch (_input.LA(1)) { + case FUNC: + case INTERFACE: + case MAP: + case STRUCT: + case CHAN: + case IDENTIFIER: + case L_PAREN: + case L_BRACKET: + case STAR: + case RECEIVE: + { + setState(597); + type_(); + } + break; + case NIL_LIT: + { + setState(598); + match(NIL_LIT); + } + break; + default: + throw new NoViableAltException(this); + } + } + } + } + setState(605); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,58,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class SelectStmtContext extends ParserRuleContext { + public TerminalNode SELECT() { return getToken(GoParser.SELECT, 0); } + public TerminalNode L_CURLY() { return getToken(GoParser.L_CURLY, 0); } + public TerminalNode R_CURLY() { return getToken(GoParser.R_CURLY, 0); } + public List commClause() { + return getRuleContexts(CommClauseContext.class); + } + public CommClauseContext commClause(int i) { + return getRuleContext(CommClauseContext.class,i); + } + public SelectStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_selectStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterSelectStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitSelectStmt(this); + } + } + + public final SelectStmtContext selectStmt() throws RecognitionException { + SelectStmtContext _localctx = new SelectStmtContext(_ctx, getState()); + enterRule(_localctx, 102, RULE_selectStmt); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(606); + match(SELECT); + setState(607); + match(L_CURLY); + setState(611); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==DEFAULT || _la==CASE) { + { + { + setState(608); + commClause(); + } + } + setState(613); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(614); + match(R_CURLY); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class CommClauseContext extends ParserRuleContext { + public CommCaseContext commCase() { + return getRuleContext(CommCaseContext.class,0); + } + public TerminalNode COLON() { return getToken(GoParser.COLON, 0); } + public StatementListContext statementList() { + return getRuleContext(StatementListContext.class,0); + } + public CommClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_commClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterCommClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitCommClause(this); + } + } + + public final CommClauseContext commClause() throws RecognitionException { + CommClauseContext _localctx = new CommClauseContext(_ctx, getState()); + enterRule(_localctx, 104, RULE_commClause); + try { + enterOuterAlt(_localctx, 1); + { + setState(616); + commCase(); + setState(617); + match(COLON); + setState(619); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,60,_ctx) ) { + case 1: + { + setState(618); + statementList(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class CommCaseContext extends ParserRuleContext { + public TerminalNode CASE() { return getToken(GoParser.CASE, 0); } + public SendStmtContext sendStmt() { + return getRuleContext(SendStmtContext.class,0); + } + public RecvStmtContext recvStmt() { + return getRuleContext(RecvStmtContext.class,0); + } + public TerminalNode DEFAULT() { return getToken(GoParser.DEFAULT, 0); } + public CommCaseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_commCase; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterCommCase(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitCommCase(this); + } + } + + public final CommCaseContext commCase() throws RecognitionException { + CommCaseContext _localctx = new CommCaseContext(_ctx, getState()); + enterRule(_localctx, 106, RULE_commCase); + try { + setState(627); + _errHandler.sync(this); + switch (_input.LA(1)) { + case CASE: + enterOuterAlt(_localctx, 1); + { + setState(621); + match(CASE); + setState(624); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,61,_ctx) ) { + case 1: + { + setState(622); + sendStmt(); + } + break; + case 2: + { + setState(623); + recvStmt(); + } + break; + } + } + break; + case DEFAULT: + enterOuterAlt(_localctx, 2); + { + setState(626); + match(DEFAULT); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RecvStmtContext extends ParserRuleContext { + public ExpressionContext recvExpr; + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public ExpressionListContext expressionList() { + return getRuleContext(ExpressionListContext.class,0); + } + public TerminalNode ASSIGN() { return getToken(GoParser.ASSIGN, 0); } + public IdentifierListContext identifierList() { + return getRuleContext(IdentifierListContext.class,0); + } + public TerminalNode DECLARE_ASSIGN() { return getToken(GoParser.DECLARE_ASSIGN, 0); } + public RecvStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_recvStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterRecvStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitRecvStmt(this); + } + } + + public final RecvStmtContext recvStmt() throws RecognitionException { + RecvStmtContext _localctx = new RecvStmtContext(_ctx, getState()); + enterRule(_localctx, 108, RULE_recvStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(635); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,63,_ctx) ) { + case 1: + { + setState(629); + expressionList(); + setState(630); + match(ASSIGN); + } + break; + case 2: + { + setState(632); + identifierList(); + setState(633); + match(DECLARE_ASSIGN); + } + break; + } + setState(637); + ((RecvStmtContext)_localctx).recvExpr = expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ForStmtContext extends ParserRuleContext { + public TerminalNode FOR() { return getToken(GoParser.FOR, 0); } + public BlockContext block() { + return getRuleContext(BlockContext.class,0); + } + public ForClauseContext forClause() { + return getRuleContext(ForClauseContext.class,0); + } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public RangeClauseContext rangeClause() { + return getRuleContext(RangeClauseContext.class,0); + } + public ForStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_forStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterForStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitForStmt(this); + } + } + + public final ForStmtContext forStmt() throws RecognitionException { + ForStmtContext _localctx = new ForStmtContext(_ctx, getState()); + enterRule(_localctx, 110, RULE_forStmt); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(639); + match(FOR); + setState(647); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,66,_ctx) ) { + case 1: + { + setState(641); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNC) | (1L << INTERFACE) | (1L << MAP) | (1L << STRUCT) | (1L << CHAN) | (1L << NIL_LIT) | (1L << IDENTIFIER) | (1L << L_PAREN) | (1L << L_BRACKET) | (1L << EXCLAMATION) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (RECEIVE - 64)) | (1L << (DECIMAL_LIT - 64)) | (1L << (BINARY_LIT - 64)) | (1L << (OCTAL_LIT - 64)) | (1L << (HEX_LIT - 64)) | (1L << (FLOAT_LIT - 64)) | (1L << (IMAGINARY_LIT - 64)) | (1L << (RUNE_LIT - 64)) | (1L << (RAW_STRING_LIT - 64)) | (1L << (INTERPRETED_STRING_LIT - 64)))) != 0)) { + { + setState(640); + expression(0); + } + } + + } + break; + case 2: + { + setState(643); + forClause(); + } + break; + case 3: + { + setState(645); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNC) | (1L << INTERFACE) | (1L << MAP) | (1L << STRUCT) | (1L << CHAN) | (1L << RANGE) | (1L << NIL_LIT) | (1L << IDENTIFIER) | (1L << L_PAREN) | (1L << L_BRACKET) | (1L << EXCLAMATION) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (RECEIVE - 64)) | (1L << (DECIMAL_LIT - 64)) | (1L << (BINARY_LIT - 64)) | (1L << (OCTAL_LIT - 64)) | (1L << (HEX_LIT - 64)) | (1L << (FLOAT_LIT - 64)) | (1L << (IMAGINARY_LIT - 64)) | (1L << (RUNE_LIT - 64)) | (1L << (RAW_STRING_LIT - 64)) | (1L << (INTERPRETED_STRING_LIT - 64)))) != 0)) { + { + setState(644); + rangeClause(); + } + } + + } + break; + } + setState(649); + block(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ForClauseContext extends ParserRuleContext { + public SimpleStmtContext initStmt; + public SimpleStmtContext postStmt; + public List eos() { + return getRuleContexts(EosContext.class); + } + public EosContext eos(int i) { + return getRuleContext(EosContext.class,i); + } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public List simpleStmt() { + return getRuleContexts(SimpleStmtContext.class); + } + public SimpleStmtContext simpleStmt(int i) { + return getRuleContext(SimpleStmtContext.class,i); + } + public ForClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_forClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterForClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitForClause(this); + } + } + + public final ForClauseContext forClause() throws RecognitionException { + ForClauseContext _localctx = new ForClauseContext(_ctx, getState()); + enterRule(_localctx, 112, RULE_forClause); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(652); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,67,_ctx) ) { + case 1: + { + setState(651); + ((ForClauseContext)_localctx).initStmt = simpleStmt(); + } + break; + } + setState(654); + eos(); + setState(656); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,68,_ctx) ) { + case 1: + { + setState(655); + expression(0); + } + break; + } + setState(658); + eos(); + setState(660); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNC) | (1L << INTERFACE) | (1L << MAP) | (1L << STRUCT) | (1L << CHAN) | (1L << NIL_LIT) | (1L << IDENTIFIER) | (1L << L_PAREN) | (1L << L_BRACKET) | (1L << EXCLAMATION) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (RECEIVE - 64)) | (1L << (DECIMAL_LIT - 64)) | (1L << (BINARY_LIT - 64)) | (1L << (OCTAL_LIT - 64)) | (1L << (HEX_LIT - 64)) | (1L << (FLOAT_LIT - 64)) | (1L << (IMAGINARY_LIT - 64)) | (1L << (RUNE_LIT - 64)) | (1L << (RAW_STRING_LIT - 64)) | (1L << (INTERPRETED_STRING_LIT - 64)))) != 0)) { + { + setState(659); + ((ForClauseContext)_localctx).postStmt = simpleStmt(); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RangeClauseContext extends ParserRuleContext { + public TerminalNode RANGE() { return getToken(GoParser.RANGE, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public ExpressionListContext expressionList() { + return getRuleContext(ExpressionListContext.class,0); + } + public TerminalNode ASSIGN() { return getToken(GoParser.ASSIGN, 0); } + public IdentifierListContext identifierList() { + return getRuleContext(IdentifierListContext.class,0); + } + public TerminalNode DECLARE_ASSIGN() { return getToken(GoParser.DECLARE_ASSIGN, 0); } + public RangeClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_rangeClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterRangeClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitRangeClause(this); + } + } + + public final RangeClauseContext rangeClause() throws RecognitionException { + RangeClauseContext _localctx = new RangeClauseContext(_ctx, getState()); + enterRule(_localctx, 114, RULE_rangeClause); + try { + enterOuterAlt(_localctx, 1); + { + setState(668); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,70,_ctx) ) { + case 1: + { + setState(662); + expressionList(); + setState(663); + match(ASSIGN); + } + break; + case 2: + { + setState(665); + identifierList(); + setState(666); + match(DECLARE_ASSIGN); + } + break; + } + setState(670); + match(RANGE); + setState(671); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class GoStmtContext extends ParserRuleContext { + public TerminalNode GO() { return getToken(GoParser.GO, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public GoStmtContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_goStmt; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterGoStmt(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitGoStmt(this); + } + } + + public final GoStmtContext goStmt() throws RecognitionException { + GoStmtContext _localctx = new GoStmtContext(_ctx, getState()); + enterRule(_localctx, 116, RULE_goStmt); + try { + enterOuterAlt(_localctx, 1); + { + setState(673); + match(GO); + setState(674); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Type_Context extends ParserRuleContext { + public TypeNameContext typeName() { + return getRuleContext(TypeNameContext.class,0); + } + public TypeArgsContext typeArgs() { + return getRuleContext(TypeArgsContext.class,0); + } + public TypeLitContext typeLit() { + return getRuleContext(TypeLitContext.class,0); + } + public TerminalNode L_PAREN() { return getToken(GoParser.L_PAREN, 0); } + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public TerminalNode R_PAREN() { return getToken(GoParser.R_PAREN, 0); } + public Type_Context(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_type_; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterType_(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitType_(this); + } + } + + public final Type_Context type_() throws RecognitionException { + Type_Context _localctx = new Type_Context(_ctx, getState()); + enterRule(_localctx, 118, RULE_type_); + try { + setState(685); + _errHandler.sync(this); + switch (_input.LA(1)) { + case IDENTIFIER: + enterOuterAlt(_localctx, 1); + { + setState(676); + typeName(); + setState(678); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,71,_ctx) ) { + case 1: + { + setState(677); + typeArgs(); + } + break; + } + } + break; + case FUNC: + case INTERFACE: + case MAP: + case STRUCT: + case CHAN: + case L_BRACKET: + case STAR: + case RECEIVE: + enterOuterAlt(_localctx, 2); + { + setState(680); + typeLit(); + } + break; + case L_PAREN: + enterOuterAlt(_localctx, 3); + { + setState(681); + match(L_PAREN); + setState(682); + type_(); + setState(683); + match(R_PAREN); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeArgsContext extends ParserRuleContext { + public TerminalNode L_BRACKET() { return getToken(GoParser.L_BRACKET, 0); } + public TypeListContext typeList() { + return getRuleContext(TypeListContext.class,0); + } + public TerminalNode R_BRACKET() { return getToken(GoParser.R_BRACKET, 0); } + public TerminalNode COMMA() { return getToken(GoParser.COMMA, 0); } + public TypeArgsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeArgs; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeArgs(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeArgs(this); + } + } + + public final TypeArgsContext typeArgs() throws RecognitionException { + TypeArgsContext _localctx = new TypeArgsContext(_ctx, getState()); + enterRule(_localctx, 120, RULE_typeArgs); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(687); + match(L_BRACKET); + setState(688); + typeList(); + setState(690); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(689); + match(COMMA); + } + } + + setState(692); + match(R_BRACKET); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeNameContext extends ParserRuleContext { + public QualifiedIdentContext qualifiedIdent() { + return getRuleContext(QualifiedIdentContext.class,0); + } + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public TypeNameContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeName; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeName(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeName(this); + } + } + + public final TypeNameContext typeName() throws RecognitionException { + TypeNameContext _localctx = new TypeNameContext(_ctx, getState()); + enterRule(_localctx, 122, RULE_typeName); + try { + setState(696); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,74,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(694); + qualifiedIdent(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(695); + match(IDENTIFIER); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeLitContext extends ParserRuleContext { + public ArrayTypeContext arrayType() { + return getRuleContext(ArrayTypeContext.class,0); + } + public StructTypeContext structType() { + return getRuleContext(StructTypeContext.class,0); + } + public PointerTypeContext pointerType() { + return getRuleContext(PointerTypeContext.class,0); + } + public FunctionTypeContext functionType() { + return getRuleContext(FunctionTypeContext.class,0); + } + public InterfaceTypeContext interfaceType() { + return getRuleContext(InterfaceTypeContext.class,0); + } + public SliceTypeContext sliceType() { + return getRuleContext(SliceTypeContext.class,0); + } + public MapTypeContext mapType() { + return getRuleContext(MapTypeContext.class,0); + } + public ChannelTypeContext channelType() { + return getRuleContext(ChannelTypeContext.class,0); + } + public TypeLitContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeLit; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeLit(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeLit(this); + } + } + + public final TypeLitContext typeLit() throws RecognitionException { + TypeLitContext _localctx = new TypeLitContext(_ctx, getState()); + enterRule(_localctx, 124, RULE_typeLit); + try { + setState(706); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,75,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(698); + arrayType(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(699); + structType(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(700); + pointerType(); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(701); + functionType(); + } + break; + case 5: + enterOuterAlt(_localctx, 5); + { + setState(702); + interfaceType(); + } + break; + case 6: + enterOuterAlt(_localctx, 6); + { + setState(703); + sliceType(); + } + break; + case 7: + enterOuterAlt(_localctx, 7); + { + setState(704); + mapType(); + } + break; + case 8: + enterOuterAlt(_localctx, 8); + { + setState(705); + channelType(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ArrayTypeContext extends ParserRuleContext { + public TerminalNode L_BRACKET() { return getToken(GoParser.L_BRACKET, 0); } + public ArrayLengthContext arrayLength() { + return getRuleContext(ArrayLengthContext.class,0); + } + public TerminalNode R_BRACKET() { return getToken(GoParser.R_BRACKET, 0); } + public ElementTypeContext elementType() { + return getRuleContext(ElementTypeContext.class,0); + } + public ArrayTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_arrayType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterArrayType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitArrayType(this); + } + } + + public final ArrayTypeContext arrayType() throws RecognitionException { + ArrayTypeContext _localctx = new ArrayTypeContext(_ctx, getState()); + enterRule(_localctx, 126, RULE_arrayType); + try { + enterOuterAlt(_localctx, 1); + { + setState(708); + match(L_BRACKET); + setState(709); + arrayLength(); + setState(710); + match(R_BRACKET); + setState(711); + elementType(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ArrayLengthContext extends ParserRuleContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public ArrayLengthContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_arrayLength; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterArrayLength(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitArrayLength(this); + } + } + + public final ArrayLengthContext arrayLength() throws RecognitionException { + ArrayLengthContext _localctx = new ArrayLengthContext(_ctx, getState()); + enterRule(_localctx, 128, RULE_arrayLength); + try { + enterOuterAlt(_localctx, 1); + { + setState(713); + expression(0); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ElementTypeContext extends ParserRuleContext { + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public ElementTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_elementType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterElementType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitElementType(this); + } + } + + public final ElementTypeContext elementType() throws RecognitionException { + ElementTypeContext _localctx = new ElementTypeContext(_ctx, getState()); + enterRule(_localctx, 130, RULE_elementType); + try { + enterOuterAlt(_localctx, 1); + { + setState(715); + type_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class PointerTypeContext extends ParserRuleContext { + public TerminalNode STAR() { return getToken(GoParser.STAR, 0); } + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public PointerTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_pointerType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterPointerType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitPointerType(this); + } + } + + public final PointerTypeContext pointerType() throws RecognitionException { + PointerTypeContext _localctx = new PointerTypeContext(_ctx, getState()); + enterRule(_localctx, 132, RULE_pointerType); + try { + enterOuterAlt(_localctx, 1); + { + setState(717); + match(STAR); + setState(718); + type_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class InterfaceTypeContext extends ParserRuleContext { + public TerminalNode INTERFACE() { return getToken(GoParser.INTERFACE, 0); } + public TerminalNode L_CURLY() { return getToken(GoParser.L_CURLY, 0); } + public TerminalNode R_CURLY() { return getToken(GoParser.R_CURLY, 0); } + public List eos() { + return getRuleContexts(EosContext.class); + } + public EosContext eos(int i) { + return getRuleContext(EosContext.class,i); + } + public List methodSpec() { + return getRuleContexts(MethodSpecContext.class); + } + public MethodSpecContext methodSpec(int i) { + return getRuleContext(MethodSpecContext.class,i); + } + public List typeElement() { + return getRuleContexts(TypeElementContext.class); + } + public TypeElementContext typeElement(int i) { + return getRuleContext(TypeElementContext.class,i); + } + public InterfaceTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_interfaceType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterInterfaceType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitInterfaceType(this); + } + } + + public final InterfaceTypeContext interfaceType() throws RecognitionException { + InterfaceTypeContext _localctx = new InterfaceTypeContext(_ctx, getState()); + enterRule(_localctx, 134, RULE_interfaceType); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(720); + match(INTERFACE); + setState(721); + match(L_CURLY); + setState(730); + _errHandler.sync(this); + _la = _input.LA(1); + while (((((_la - 3)) & ~0x3f) == 0 && ((1L << (_la - 3)) & ((1L << (FUNC - 3)) | (1L << (INTERFACE - 3)) | (1L << (MAP - 3)) | (1L << (STRUCT - 3)) | (1L << (CHAN - 3)) | (1L << (IDENTIFIER - 3)) | (1L << (L_PAREN - 3)) | (1L << (L_BRACKET - 3)) | (1L << (UNDERLYING - 3)) | (1L << (STAR - 3)) | (1L << (RECEIVE - 3)))) != 0)) { + { + { + setState(724); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,76,_ctx) ) { + case 1: + { + setState(722); + methodSpec(); + } + break; + case 2: + { + setState(723); + typeElement(); + } + break; + } + setState(726); + eos(); + } + } + setState(732); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(733); + match(R_CURLY); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class SliceTypeContext extends ParserRuleContext { + public TerminalNode L_BRACKET() { return getToken(GoParser.L_BRACKET, 0); } + public TerminalNode R_BRACKET() { return getToken(GoParser.R_BRACKET, 0); } + public ElementTypeContext elementType() { + return getRuleContext(ElementTypeContext.class,0); + } + public SliceTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_sliceType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterSliceType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitSliceType(this); + } + } + + public final SliceTypeContext sliceType() throws RecognitionException { + SliceTypeContext _localctx = new SliceTypeContext(_ctx, getState()); + enterRule(_localctx, 136, RULE_sliceType); + try { + enterOuterAlt(_localctx, 1); + { + setState(735); + match(L_BRACKET); + setState(736); + match(R_BRACKET); + setState(737); + elementType(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class MapTypeContext extends ParserRuleContext { + public TerminalNode MAP() { return getToken(GoParser.MAP, 0); } + public TerminalNode L_BRACKET() { return getToken(GoParser.L_BRACKET, 0); } + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public TerminalNode R_BRACKET() { return getToken(GoParser.R_BRACKET, 0); } + public ElementTypeContext elementType() { + return getRuleContext(ElementTypeContext.class,0); + } + public MapTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_mapType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterMapType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitMapType(this); + } + } + + public final MapTypeContext mapType() throws RecognitionException { + MapTypeContext _localctx = new MapTypeContext(_ctx, getState()); + enterRule(_localctx, 138, RULE_mapType); + try { + enterOuterAlt(_localctx, 1); + { + setState(739); + match(MAP); + setState(740); + match(L_BRACKET); + setState(741); + type_(); + setState(742); + match(R_BRACKET); + setState(743); + elementType(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ChannelTypeContext extends ParserRuleContext { + public ElementTypeContext elementType() { + return getRuleContext(ElementTypeContext.class,0); + } + public TerminalNode CHAN() { return getToken(GoParser.CHAN, 0); } + public TerminalNode RECEIVE() { return getToken(GoParser.RECEIVE, 0); } + public ChannelTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_channelType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterChannelType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitChannelType(this); + } + } + + public final ChannelTypeContext channelType() throws RecognitionException { + ChannelTypeContext _localctx = new ChannelTypeContext(_ctx, getState()); + enterRule(_localctx, 140, RULE_channelType); + try { + enterOuterAlt(_localctx, 1); + { + setState(750); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,78,_ctx) ) { + case 1: + { + setState(745); + match(CHAN); + } + break; + case 2: + { + setState(746); + match(CHAN); + setState(747); + match(RECEIVE); + } + break; + case 3: + { + setState(748); + match(RECEIVE); + setState(749); + match(CHAN); + } + break; + } + setState(752); + elementType(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class MethodSpecContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public ResultContext result() { + return getRuleContext(ResultContext.class,0); + } + public MethodSpecContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_methodSpec; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterMethodSpec(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitMethodSpec(this); + } + } + + public final MethodSpecContext methodSpec() throws RecognitionException { + MethodSpecContext _localctx = new MethodSpecContext(_ctx, getState()); + enterRule(_localctx, 142, RULE_methodSpec); + try { + setState(760); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,79,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(754); + match(IDENTIFIER); + setState(755); + parameters(); + setState(756); + result(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(758); + match(IDENTIFIER); + setState(759); + parameters(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class FunctionTypeContext extends ParserRuleContext { + public TerminalNode FUNC() { return getToken(GoParser.FUNC, 0); } + public SignatureContext signature() { + return getRuleContext(SignatureContext.class,0); + } + public FunctionTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterFunctionType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitFunctionType(this); + } + } + + public final FunctionTypeContext functionType() throws RecognitionException { + FunctionTypeContext _localctx = new FunctionTypeContext(_ctx, getState()); + enterRule(_localctx, 144, RULE_functionType); + try { + enterOuterAlt(_localctx, 1); + { + setState(762); + match(FUNC); + setState(763); + signature(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class SignatureContext extends ParserRuleContext { + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public ResultContext result() { + return getRuleContext(ResultContext.class,0); + } + public SignatureContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_signature; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterSignature(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitSignature(this); + } + } + + public final SignatureContext signature() throws RecognitionException { + SignatureContext _localctx = new SignatureContext(_ctx, getState()); + enterRule(_localctx, 146, RULE_signature); + try { + enterOuterAlt(_localctx, 1); + { + setState(765); + parameters(); + setState(767); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,80,_ctx) ) { + case 1: + { + setState(766); + result(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ResultContext extends ParserRuleContext { + public ParametersContext parameters() { + return getRuleContext(ParametersContext.class,0); + } + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public ResultContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_result; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterResult(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitResult(this); + } + } + + public final ResultContext result() throws RecognitionException { + ResultContext _localctx = new ResultContext(_ctx, getState()); + enterRule(_localctx, 148, RULE_result); + try { + setState(771); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,81,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(769); + parameters(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(770); + type_(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ParametersContext extends ParserRuleContext { + public TerminalNode L_PAREN() { return getToken(GoParser.L_PAREN, 0); } + public TerminalNode R_PAREN() { return getToken(GoParser.R_PAREN, 0); } + public List parameterDecl() { + return getRuleContexts(ParameterDeclContext.class); + } + public ParameterDeclContext parameterDecl(int i) { + return getRuleContext(ParameterDeclContext.class,i); + } + public List COMMA() { return getTokens(GoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(GoParser.COMMA, i); + } + public ParametersContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_parameters; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterParameters(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitParameters(this); + } + } + + public final ParametersContext parameters() throws RecognitionException { + ParametersContext _localctx = new ParametersContext(_ctx, getState()); + enterRule(_localctx, 150, RULE_parameters); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(773); + match(L_PAREN); + setState(785); + _errHandler.sync(this); + _la = _input.LA(1); + if (((((_la - 3)) & ~0x3f) == 0 && ((1L << (_la - 3)) & ((1L << (FUNC - 3)) | (1L << (INTERFACE - 3)) | (1L << (MAP - 3)) | (1L << (STRUCT - 3)) | (1L << (CHAN - 3)) | (1L << (IDENTIFIER - 3)) | (1L << (L_PAREN - 3)) | (1L << (L_BRACKET - 3)) | (1L << (ELLIPSIS - 3)) | (1L << (STAR - 3)) | (1L << (RECEIVE - 3)))) != 0)) { + { + setState(774); + parameterDecl(); + setState(779); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,82,_ctx); + while ( _alt!=2 && _alt!= ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(775); + match(COMMA); + setState(776); + parameterDecl(); + } + } + } + setState(781); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,82,_ctx); + } + setState(783); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(782); + match(COMMA); + } + } + + } + } + + setState(787); + match(R_PAREN); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ParameterDeclContext extends ParserRuleContext { + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public IdentifierListContext identifierList() { + return getRuleContext(IdentifierListContext.class,0); + } + public TerminalNode ELLIPSIS() { return getToken(GoParser.ELLIPSIS, 0); } + public ParameterDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_parameterDecl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterParameterDecl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitParameterDecl(this); + } + } + + public final ParameterDeclContext parameterDecl() throws RecognitionException { + ParameterDeclContext _localctx = new ParameterDeclContext(_ctx, getState()); + enterRule(_localctx, 152, RULE_parameterDecl); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(790); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,85,_ctx) ) { + case 1: + { + setState(789); + identifierList(); + } + break; + } + setState(793); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==ELLIPSIS) { + { + setState(792); + match(ELLIPSIS); + } + } + + setState(795); + type_(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ExpressionContext extends ParserRuleContext { + public Token unary_op; + public Token mul_op; + public Token add_op; + public Token rel_op; + public PrimaryExprContext primaryExpr() { + return getRuleContext(PrimaryExprContext.class,0); + } + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public TerminalNode PLUS() { return getToken(GoParser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(GoParser.MINUS, 0); } + public TerminalNode EXCLAMATION() { return getToken(GoParser.EXCLAMATION, 0); } + public TerminalNode CARET() { return getToken(GoParser.CARET, 0); } + public TerminalNode STAR() { return getToken(GoParser.STAR, 0); } + public TerminalNode AMPERSAND() { return getToken(GoParser.AMPERSAND, 0); } + public TerminalNode RECEIVE() { return getToken(GoParser.RECEIVE, 0); } + public TerminalNode DIV() { return getToken(GoParser.DIV, 0); } + public TerminalNode MOD() { return getToken(GoParser.MOD, 0); } + public TerminalNode LSHIFT() { return getToken(GoParser.LSHIFT, 0); } + public TerminalNode RSHIFT() { return getToken(GoParser.RSHIFT, 0); } + public TerminalNode BIT_CLEAR() { return getToken(GoParser.BIT_CLEAR, 0); } + public TerminalNode OR() { return getToken(GoParser.OR, 0); } + public TerminalNode EQUALS() { return getToken(GoParser.EQUALS, 0); } + public TerminalNode NOT_EQUALS() { return getToken(GoParser.NOT_EQUALS, 0); } + public TerminalNode LESS() { return getToken(GoParser.LESS, 0); } + public TerminalNode LESS_OR_EQUALS() { return getToken(GoParser.LESS_OR_EQUALS, 0); } + public TerminalNode GREATER() { return getToken(GoParser.GREATER, 0); } + public TerminalNode GREATER_OR_EQUALS() { return getToken(GoParser.GREATER_OR_EQUALS, 0); } + public TerminalNode LOGICAL_AND() { return getToken(GoParser.LOGICAL_AND, 0); } + public TerminalNode LOGICAL_OR() { return getToken(GoParser.LOGICAL_OR, 0); } + public ExpressionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_expression; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterExpression(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitExpression(this); + } + } + + public final ExpressionContext expression() throws RecognitionException { + return expression(0); + } + + private ExpressionContext expression(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + ExpressionContext _localctx = new ExpressionContext(_ctx, _parentState); + ExpressionContext _prevctx = _localctx; + int _startState = 154; + enterRecursionRule(_localctx, 154, RULE_expression, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(801); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,87,_ctx) ) { + case 1: + { + setState(798); + primaryExpr(0); + } + break; + case 2: + { + setState(799); + ((ExpressionContext)_localctx).unary_op = _input.LT(1); + _la = _input.LA(1); + if ( !(((((_la - 58)) & ~0x3f) == 0 && ((1L << (_la - 58)) & ((1L << (EXCLAMATION - 58)) | (1L << (PLUS - 58)) | (1L << (MINUS - 58)) | (1L << (CARET - 58)) | (1L << (STAR - 58)) | (1L << (AMPERSAND - 58)) | (1L << (RECEIVE - 58)))) != 0)) ) { + ((ExpressionContext)_localctx).unary_op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(800); + expression(6); + } + break; + } + _ctx.stop = _input.LT(-1); + setState(820); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,89,_ctx); + while ( _alt!=2 && _alt!= ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(818); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,88,_ctx) ) { + case 1: + { + _localctx = new ExpressionContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(803); + if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)"); + setState(804); + ((ExpressionContext)_localctx).mul_op = _input.LT(1); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << DIV) | (1L << MOD) | (1L << LSHIFT) | (1L << RSHIFT) | (1L << BIT_CLEAR) | (1L << STAR) | (1L << AMPERSAND))) != 0)) ) { + ((ExpressionContext)_localctx).mul_op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(805); + expression(6); + } + break; + case 2: + { + _localctx = new ExpressionContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(806); + if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); + setState(807); + ((ExpressionContext)_localctx).add_op = _input.LT(1); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << OR) | (1L << PLUS) | (1L << MINUS) | (1L << CARET))) != 0)) ) { + ((ExpressionContext)_localctx).add_op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(808); + expression(5); + } + break; + case 3: + { + _localctx = new ExpressionContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(809); + if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); + setState(810); + ((ExpressionContext)_localctx).rel_op = _input.LT(1); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << EQUALS) | (1L << NOT_EQUALS) | (1L << LESS) | (1L << LESS_OR_EQUALS) | (1L << GREATER) | (1L << GREATER_OR_EQUALS))) != 0)) ) { + ((ExpressionContext)_localctx).rel_op = (Token)_errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + setState(811); + expression(4); + } + break; + case 4: + { + _localctx = new ExpressionContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(812); + if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); + setState(813); + match(LOGICAL_AND); + setState(814); + expression(3); + } + break; + case 5: + { + _localctx = new ExpressionContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_expression); + setState(815); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(816); + match(LOGICAL_OR); + setState(817); + expression(2); + } + break; + } + } + } + setState(822); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,89,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + public static class PrimaryExprContext extends ParserRuleContext { + public OperandContext operand() { + return getRuleContext(OperandContext.class,0); + } + public ConversionContext conversion() { + return getRuleContext(ConversionContext.class,0); + } + public MethodExprContext methodExpr() { + return getRuleContext(MethodExprContext.class,0); + } + public PrimaryExprContext primaryExpr() { + return getRuleContext(PrimaryExprContext.class,0); + } + public TerminalNode DOT() { return getToken(GoParser.DOT, 0); } + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public IndexContext index() { + return getRuleContext(IndexContext.class,0); + } + public Slice_Context slice_() { + return getRuleContext(Slice_Context.class,0); + } + public TypeAssertionContext typeAssertion() { + return getRuleContext(TypeAssertionContext.class,0); + } + public ArgumentsContext arguments() { + return getRuleContext(ArgumentsContext.class,0); + } + public PrimaryExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_primaryExpr; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterPrimaryExpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitPrimaryExpr(this); + } + } + + public final PrimaryExprContext primaryExpr() throws RecognitionException { + return primaryExpr(0); + } + + private PrimaryExprContext primaryExpr(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + PrimaryExprContext _localctx = new PrimaryExprContext(_ctx, _parentState); + PrimaryExprContext _prevctx = _localctx; + int _startState = 156; + enterRecursionRule(_localctx, 156, RULE_primaryExpr, _p); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(827); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,90,_ctx) ) { + case 1: + { + setState(824); + operand(); + } + break; + case 2: + { + setState(825); + conversion(); + } + break; + case 3: + { + setState(826); + methodExpr(); + } + break; + } + _ctx.stop = _input.LT(-1); + setState(840); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,92,_ctx); + while ( _alt!=2 && _alt!= ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + { + _localctx = new PrimaryExprContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_primaryExpr); + setState(829); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(836); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,91,_ctx) ) { + case 1: + { + setState(830); + match(DOT); + setState(831); + match(IDENTIFIER); + } + break; + case 2: + { + setState(832); + index(); + } + break; + case 3: + { + setState(833); + slice_(); + } + break; + case 4: + { + setState(834); + typeAssertion(); + } + break; + case 5: + { + setState(835); + arguments(); + } + break; + } + } + } + } + setState(842); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,92,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + public static class ConversionContext extends ParserRuleContext { + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public TerminalNode L_PAREN() { return getToken(GoParser.L_PAREN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode R_PAREN() { return getToken(GoParser.R_PAREN, 0); } + public TerminalNode COMMA() { return getToken(GoParser.COMMA, 0); } + public ConversionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_conversion; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterConversion(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitConversion(this); + } + } + + public final ConversionContext conversion() throws RecognitionException { + ConversionContext _localctx = new ConversionContext(_ctx, getState()); + enterRule(_localctx, 158, RULE_conversion); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(843); + type_(); + setState(844); + match(L_PAREN); + setState(845); + expression(0); + setState(847); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(846); + match(COMMA); + } + } + + setState(849); + match(R_PAREN); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class OperandContext extends ParserRuleContext { + public LiteralContext literal() { + return getRuleContext(LiteralContext.class,0); + } + public OperandNameContext operandName() { + return getRuleContext(OperandNameContext.class,0); + } + public TypeArgsContext typeArgs() { + return getRuleContext(TypeArgsContext.class,0); + } + public TerminalNode L_PAREN() { return getToken(GoParser.L_PAREN, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode R_PAREN() { return getToken(GoParser.R_PAREN, 0); } + public OperandContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_operand; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterOperand(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitOperand(this); + } + } + + public final OperandContext operand() throws RecognitionException { + OperandContext _localctx = new OperandContext(_ctx, getState()); + enterRule(_localctx, 160, RULE_operand); + try { + setState(860); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,95,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(851); + literal(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(852); + operandName(); + setState(854); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,94,_ctx) ) { + case 1: + { + setState(853); + typeArgs(); + } + break; + } + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(856); + match(L_PAREN); + setState(857); + expression(0); + setState(858); + match(R_PAREN); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class LiteralContext extends ParserRuleContext { + public BasicLitContext basicLit() { + return getRuleContext(BasicLitContext.class,0); + } + public CompositeLitContext compositeLit() { + return getRuleContext(CompositeLitContext.class,0); + } + public FunctionLitContext functionLit() { + return getRuleContext(FunctionLitContext.class,0); + } + public LiteralContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_literal; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterLiteral(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitLiteral(this); + } + } + + public final LiteralContext literal() throws RecognitionException { + LiteralContext _localctx = new LiteralContext(_ctx, getState()); + enterRule(_localctx, 162, RULE_literal); + try { + setState(865); + _errHandler.sync(this); + switch (_input.LA(1)) { + case NIL_LIT: + case DECIMAL_LIT: + case BINARY_LIT: + case OCTAL_LIT: + case HEX_LIT: + case FLOAT_LIT: + case IMAGINARY_LIT: + case RUNE_LIT: + case RAW_STRING_LIT: + case INTERPRETED_STRING_LIT: + enterOuterAlt(_localctx, 1); + { + setState(862); + basicLit(); + } + break; + case MAP: + case STRUCT: + case IDENTIFIER: + case L_BRACKET: + enterOuterAlt(_localctx, 2); + { + setState(863); + compositeLit(); + } + break; + case FUNC: + enterOuterAlt(_localctx, 3); + { + setState(864); + functionLit(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class BasicLitContext extends ParserRuleContext { + public TerminalNode NIL_LIT() { return getToken(GoParser.NIL_LIT, 0); } + public IntegerContext integer() { + return getRuleContext(IntegerContext.class,0); + } + public String_Context string_() { + return getRuleContext(String_Context.class,0); + } + public TerminalNode FLOAT_LIT() { return getToken(GoParser.FLOAT_LIT, 0); } + public BasicLitContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_basicLit; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterBasicLit(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitBasicLit(this); + } + } + + public final BasicLitContext basicLit() throws RecognitionException { + BasicLitContext _localctx = new BasicLitContext(_ctx, getState()); + enterRule(_localctx, 164, RULE_basicLit); + try { + setState(871); + _errHandler.sync(this); + switch (_input.LA(1)) { + case NIL_LIT: + enterOuterAlt(_localctx, 1); + { + setState(867); + match(NIL_LIT); + } + break; + case DECIMAL_LIT: + case BINARY_LIT: + case OCTAL_LIT: + case HEX_LIT: + case IMAGINARY_LIT: + case RUNE_LIT: + enterOuterAlt(_localctx, 2); + { + setState(868); + integer(); + } + break; + case RAW_STRING_LIT: + case INTERPRETED_STRING_LIT: + enterOuterAlt(_localctx, 3); + { + setState(869); + string_(); + } + break; + case FLOAT_LIT: + enterOuterAlt(_localctx, 4); + { + setState(870); + match(FLOAT_LIT); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class IntegerContext extends ParserRuleContext { + public TerminalNode DECIMAL_LIT() { return getToken(GoParser.DECIMAL_LIT, 0); } + public TerminalNode BINARY_LIT() { return getToken(GoParser.BINARY_LIT, 0); } + public TerminalNode OCTAL_LIT() { return getToken(GoParser.OCTAL_LIT, 0); } + public TerminalNode HEX_LIT() { return getToken(GoParser.HEX_LIT, 0); } + public TerminalNode IMAGINARY_LIT() { return getToken(GoParser.IMAGINARY_LIT, 0); } + public TerminalNode RUNE_LIT() { return getToken(GoParser.RUNE_LIT, 0); } + public IntegerContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_integer; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterInteger(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitInteger(this); + } + } + + public final IntegerContext integer() throws RecognitionException { + IntegerContext _localctx = new IntegerContext(_ctx, getState()); + enterRule(_localctx, 166, RULE_integer); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(873); + _la = _input.LA(1); + if ( !(((((_la - 65)) & ~0x3f) == 0 && ((1L << (_la - 65)) & ((1L << (DECIMAL_LIT - 65)) | (1L << (BINARY_LIT - 65)) | (1L << (OCTAL_LIT - 65)) | (1L << (HEX_LIT - 65)) | (1L << (IMAGINARY_LIT - 65)) | (1L << (RUNE_LIT - 65)))) != 0)) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class OperandNameContext extends ParserRuleContext { + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public OperandNameContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_operandName; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterOperandName(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitOperandName(this); + } + } + + public final OperandNameContext operandName() throws RecognitionException { + OperandNameContext _localctx = new OperandNameContext(_ctx, getState()); + enterRule(_localctx, 168, RULE_operandName); + try { + enterOuterAlt(_localctx, 1); + { + setState(875); + match(IDENTIFIER); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class QualifiedIdentContext extends ParserRuleContext { + public List IDENTIFIER() { return getTokens(GoParser.IDENTIFIER); } + public TerminalNode IDENTIFIER(int i) { + return getToken(GoParser.IDENTIFIER, i); + } + public TerminalNode DOT() { return getToken(GoParser.DOT, 0); } + public QualifiedIdentContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_qualifiedIdent; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterQualifiedIdent(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitQualifiedIdent(this); + } + } + + public final QualifiedIdentContext qualifiedIdent() throws RecognitionException { + QualifiedIdentContext _localctx = new QualifiedIdentContext(_ctx, getState()); + enterRule(_localctx, 170, RULE_qualifiedIdent); + try { + enterOuterAlt(_localctx, 1); + { + setState(877); + match(IDENTIFIER); + setState(878); + match(DOT); + setState(879); + match(IDENTIFIER); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class CompositeLitContext extends ParserRuleContext { + public LiteralTypeContext literalType() { + return getRuleContext(LiteralTypeContext.class,0); + } + public LiteralValueContext literalValue() { + return getRuleContext(LiteralValueContext.class,0); + } + public CompositeLitContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_compositeLit; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterCompositeLit(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitCompositeLit(this); + } + } + + public final CompositeLitContext compositeLit() throws RecognitionException { + CompositeLitContext _localctx = new CompositeLitContext(_ctx, getState()); + enterRule(_localctx, 172, RULE_compositeLit); + try { + enterOuterAlt(_localctx, 1); + { + setState(881); + literalType(); + setState(882); + literalValue(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class LiteralTypeContext extends ParserRuleContext { + public StructTypeContext structType() { + return getRuleContext(StructTypeContext.class,0); + } + public ArrayTypeContext arrayType() { + return getRuleContext(ArrayTypeContext.class,0); + } + public TerminalNode L_BRACKET() { return getToken(GoParser.L_BRACKET, 0); } + public TerminalNode ELLIPSIS() { return getToken(GoParser.ELLIPSIS, 0); } + public TerminalNode R_BRACKET() { return getToken(GoParser.R_BRACKET, 0); } + public ElementTypeContext elementType() { + return getRuleContext(ElementTypeContext.class,0); + } + public SliceTypeContext sliceType() { + return getRuleContext(SliceTypeContext.class,0); + } + public MapTypeContext mapType() { + return getRuleContext(MapTypeContext.class,0); + } + public TypeNameContext typeName() { + return getRuleContext(TypeNameContext.class,0); + } + public TypeArgsContext typeArgs() { + return getRuleContext(TypeArgsContext.class,0); + } + public LiteralTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_literalType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterLiteralType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitLiteralType(this); + } + } + + public final LiteralTypeContext literalType() throws RecognitionException { + LiteralTypeContext _localctx = new LiteralTypeContext(_ctx, getState()); + enterRule(_localctx, 174, RULE_literalType); + int _la; + try { + setState(896); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,99,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(884); + structType(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(885); + arrayType(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(886); + match(L_BRACKET); + setState(887); + match(ELLIPSIS); + setState(888); + match(R_BRACKET); + setState(889); + elementType(); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(890); + sliceType(); + } + break; + case 5: + enterOuterAlt(_localctx, 5); + { + setState(891); + mapType(); + } + break; + case 6: + enterOuterAlt(_localctx, 6); + { + setState(892); + typeName(); + setState(894); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==L_BRACKET) { + { + setState(893); + typeArgs(); + } + } + + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class LiteralValueContext extends ParserRuleContext { + public TerminalNode L_CURLY() { return getToken(GoParser.L_CURLY, 0); } + public TerminalNode R_CURLY() { return getToken(GoParser.R_CURLY, 0); } + public ElementListContext elementList() { + return getRuleContext(ElementListContext.class,0); + } + public TerminalNode COMMA() { return getToken(GoParser.COMMA, 0); } + public LiteralValueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_literalValue; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterLiteralValue(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitLiteralValue(this); + } + } + + public final LiteralValueContext literalValue() throws RecognitionException { + LiteralValueContext _localctx = new LiteralValueContext(_ctx, getState()); + enterRule(_localctx, 176, RULE_literalValue); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(898); + match(L_CURLY); + setState(903); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNC) | (1L << INTERFACE) | (1L << MAP) | (1L << STRUCT) | (1L << CHAN) | (1L << NIL_LIT) | (1L << IDENTIFIER) | (1L << L_PAREN) | (1L << L_CURLY) | (1L << L_BRACKET) | (1L << EXCLAMATION) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (RECEIVE - 64)) | (1L << (DECIMAL_LIT - 64)) | (1L << (BINARY_LIT - 64)) | (1L << (OCTAL_LIT - 64)) | (1L << (HEX_LIT - 64)) | (1L << (FLOAT_LIT - 64)) | (1L << (IMAGINARY_LIT - 64)) | (1L << (RUNE_LIT - 64)) | (1L << (RAW_STRING_LIT - 64)) | (1L << (INTERPRETED_STRING_LIT - 64)))) != 0)) { + { + setState(899); + elementList(); + setState(901); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(900); + match(COMMA); + } + } + + } + } + + setState(905); + match(R_CURLY); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ElementListContext extends ParserRuleContext { + public List keyedElement() { + return getRuleContexts(KeyedElementContext.class); + } + public KeyedElementContext keyedElement(int i) { + return getRuleContext(KeyedElementContext.class,i); + } + public List COMMA() { return getTokens(GoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(GoParser.COMMA, i); + } + public ElementListContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_elementList; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterElementList(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitElementList(this); + } + } + + public final ElementListContext elementList() throws RecognitionException { + ElementListContext _localctx = new ElementListContext(_ctx, getState()); + enterRule(_localctx, 178, RULE_elementList); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(907); + keyedElement(); + setState(912); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,102,_ctx); + while ( _alt!=2 && _alt!= ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + { + { + setState(908); + match(COMMA); + setState(909); + keyedElement(); + } + } + } + setState(914); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,102,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class KeyedElementContext extends ParserRuleContext { + public ElementContext element() { + return getRuleContext(ElementContext.class,0); + } + public KeyContext key() { + return getRuleContext(KeyContext.class,0); + } + public TerminalNode COLON() { return getToken(GoParser.COLON, 0); } + public KeyedElementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_keyedElement; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterKeyedElement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitKeyedElement(this); + } + } + + public final KeyedElementContext keyedElement() throws RecognitionException { + KeyedElementContext _localctx = new KeyedElementContext(_ctx, getState()); + enterRule(_localctx, 180, RULE_keyedElement); + try { + enterOuterAlt(_localctx, 1); + { + setState(918); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,103,_ctx) ) { + case 1: + { + setState(915); + key(); + setState(916); + match(COLON); + } + break; + } + setState(920); + element(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class KeyContext extends ParserRuleContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public LiteralValueContext literalValue() { + return getRuleContext(LiteralValueContext.class,0); + } + public KeyContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_key; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterKey(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitKey(this); + } + } + + public final KeyContext key() throws RecognitionException { + KeyContext _localctx = new KeyContext(_ctx, getState()); + enterRule(_localctx, 182, RULE_key); + try { + setState(924); + _errHandler.sync(this); + switch (_input.LA(1)) { + case FUNC: + case INTERFACE: + case MAP: + case STRUCT: + case CHAN: + case NIL_LIT: + case IDENTIFIER: + case L_PAREN: + case L_BRACKET: + case EXCLAMATION: + case PLUS: + case MINUS: + case CARET: + case STAR: + case AMPERSAND: + case RECEIVE: + case DECIMAL_LIT: + case BINARY_LIT: + case OCTAL_LIT: + case HEX_LIT: + case FLOAT_LIT: + case IMAGINARY_LIT: + case RUNE_LIT: + case RAW_STRING_LIT: + case INTERPRETED_STRING_LIT: + enterOuterAlt(_localctx, 1); + { + setState(922); + expression(0); + } + break; + case L_CURLY: + enterOuterAlt(_localctx, 2); + { + setState(923); + literalValue(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ElementContext extends ParserRuleContext { + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public LiteralValueContext literalValue() { + return getRuleContext(LiteralValueContext.class,0); + } + public ElementContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_element; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterElement(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitElement(this); + } + } + + public final ElementContext element() throws RecognitionException { + ElementContext _localctx = new ElementContext(_ctx, getState()); + enterRule(_localctx, 184, RULE_element); + try { + setState(928); + _errHandler.sync(this); + switch (_input.LA(1)) { + case FUNC: + case INTERFACE: + case MAP: + case STRUCT: + case CHAN: + case NIL_LIT: + case IDENTIFIER: + case L_PAREN: + case L_BRACKET: + case EXCLAMATION: + case PLUS: + case MINUS: + case CARET: + case STAR: + case AMPERSAND: + case RECEIVE: + case DECIMAL_LIT: + case BINARY_LIT: + case OCTAL_LIT: + case HEX_LIT: + case FLOAT_LIT: + case IMAGINARY_LIT: + case RUNE_LIT: + case RAW_STRING_LIT: + case INTERPRETED_STRING_LIT: + enterOuterAlt(_localctx, 1); + { + setState(926); + expression(0); + } + break; + case L_CURLY: + enterOuterAlt(_localctx, 2); + { + setState(927); + literalValue(); + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class StructTypeContext extends ParserRuleContext { + public TerminalNode STRUCT() { return getToken(GoParser.STRUCT, 0); } + public TerminalNode L_CURLY() { return getToken(GoParser.L_CURLY, 0); } + public TerminalNode R_CURLY() { return getToken(GoParser.R_CURLY, 0); } + public List fieldDecl() { + return getRuleContexts(FieldDeclContext.class); + } + public FieldDeclContext fieldDecl(int i) { + return getRuleContext(FieldDeclContext.class,i); + } + public List eos() { + return getRuleContexts(EosContext.class); + } + public EosContext eos(int i) { + return getRuleContext(EosContext.class,i); + } + public StructTypeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_structType; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterStructType(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitStructType(this); + } + } + + public final StructTypeContext structType() throws RecognitionException { + StructTypeContext _localctx = new StructTypeContext(_ctx, getState()); + enterRule(_localctx, 186, RULE_structType); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(930); + match(STRUCT); + setState(931); + match(L_CURLY); + setState(937); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==IDENTIFIER || _la==STAR) { + { + { + setState(932); + fieldDecl(); + setState(933); + eos(); + } + } + setState(939); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(940); + match(R_CURLY); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class FieldDeclContext extends ParserRuleContext { + public String_Context tag; + public IdentifierListContext identifierList() { + return getRuleContext(IdentifierListContext.class,0); + } + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public EmbeddedFieldContext embeddedField() { + return getRuleContext(EmbeddedFieldContext.class,0); + } + public String_Context string_() { + return getRuleContext(String_Context.class,0); + } + public FieldDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_fieldDecl; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterFieldDecl(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitFieldDecl(this); + } + } + + public final FieldDeclContext fieldDecl() throws RecognitionException { + FieldDeclContext _localctx = new FieldDeclContext(_ctx, getState()); + enterRule(_localctx, 188, RULE_fieldDecl); + try { + enterOuterAlt(_localctx, 1); + { + setState(946); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,107,_ctx) ) { + case 1: + { + setState(942); + identifierList(); + setState(943); + type_(); + } + break; + case 2: + { + setState(945); + embeddedField(); + } + break; + } + setState(949); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,108,_ctx) ) { + case 1: + { + setState(948); + ((FieldDeclContext)_localctx).tag = string_(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class String_Context extends ParserRuleContext { + public TerminalNode RAW_STRING_LIT() { return getToken(GoParser.RAW_STRING_LIT, 0); } + public TerminalNode INTERPRETED_STRING_LIT() { return getToken(GoParser.INTERPRETED_STRING_LIT, 0); } + public String_Context(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_string_; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterString_(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitString_(this); + } + } + + public final String_Context string_() throws RecognitionException { + String_Context _localctx = new String_Context(_ctx, getState()); + enterRule(_localctx, 190, RULE_string_); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(951); + _la = _input.LA(1); + if ( !(_la==RAW_STRING_LIT || _la==INTERPRETED_STRING_LIT) ) { + _errHandler.recoverInline(this); + } + else { + if ( _input.LA(1)==Token.EOF ) matchedEOF = true; + _errHandler.reportMatch(this); + consume(); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class EmbeddedFieldContext extends ParserRuleContext { + public TypeNameContext typeName() { + return getRuleContext(TypeNameContext.class,0); + } + public TerminalNode STAR() { return getToken(GoParser.STAR, 0); } + public TypeArgsContext typeArgs() { + return getRuleContext(TypeArgsContext.class,0); + } + public EmbeddedFieldContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_embeddedField; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterEmbeddedField(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitEmbeddedField(this); + } + } + + public final EmbeddedFieldContext embeddedField() throws RecognitionException { + EmbeddedFieldContext _localctx = new EmbeddedFieldContext(_ctx, getState()); + enterRule(_localctx, 192, RULE_embeddedField); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(954); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==STAR) { + { + setState(953); + match(STAR); + } + } + + setState(956); + typeName(); + setState(958); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,110,_ctx) ) { + case 1: + { + setState(957); + typeArgs(); + } + break; + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class FunctionLitContext extends ParserRuleContext { + public TerminalNode FUNC() { return getToken(GoParser.FUNC, 0); } + public SignatureContext signature() { + return getRuleContext(SignatureContext.class,0); + } + public BlockContext block() { + return getRuleContext(BlockContext.class,0); + } + public FunctionLitContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_functionLit; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterFunctionLit(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitFunctionLit(this); + } + } + + public final FunctionLitContext functionLit() throws RecognitionException { + FunctionLitContext _localctx = new FunctionLitContext(_ctx, getState()); + enterRule(_localctx, 194, RULE_functionLit); + try { + enterOuterAlt(_localctx, 1); + { + setState(960); + match(FUNC); + setState(961); + signature(); + setState(962); + block(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class IndexContext extends ParserRuleContext { + public TerminalNode L_BRACKET() { return getToken(GoParser.L_BRACKET, 0); } + public ExpressionContext expression() { + return getRuleContext(ExpressionContext.class,0); + } + public TerminalNode R_BRACKET() { return getToken(GoParser.R_BRACKET, 0); } + public IndexContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_index; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterIndex(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitIndex(this); + } + } + + public final IndexContext index() throws RecognitionException { + IndexContext _localctx = new IndexContext(_ctx, getState()); + enterRule(_localctx, 196, RULE_index); + try { + enterOuterAlt(_localctx, 1); + { + setState(964); + match(L_BRACKET); + setState(965); + expression(0); + setState(966); + match(R_BRACKET); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class Slice_Context extends ParserRuleContext { + public TerminalNode L_BRACKET() { return getToken(GoParser.L_BRACKET, 0); } + public TerminalNode R_BRACKET() { return getToken(GoParser.R_BRACKET, 0); } + public List COLON() { return getTokens(GoParser.COLON); } + public TerminalNode COLON(int i) { + return getToken(GoParser.COLON, i); + } + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public Slice_Context(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_slice_; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterSlice_(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitSlice_(this); + } + } + + public final Slice_Context slice_() throws RecognitionException { + Slice_Context _localctx = new Slice_Context(_ctx, getState()); + enterRule(_localctx, 198, RULE_slice_); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(968); + match(L_BRACKET); + setState(984); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,114,_ctx) ) { + case 1: + { + setState(970); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNC) | (1L << INTERFACE) | (1L << MAP) | (1L << STRUCT) | (1L << CHAN) | (1L << NIL_LIT) | (1L << IDENTIFIER) | (1L << L_PAREN) | (1L << L_BRACKET) | (1L << EXCLAMATION) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (RECEIVE - 64)) | (1L << (DECIMAL_LIT - 64)) | (1L << (BINARY_LIT - 64)) | (1L << (OCTAL_LIT - 64)) | (1L << (HEX_LIT - 64)) | (1L << (FLOAT_LIT - 64)) | (1L << (IMAGINARY_LIT - 64)) | (1L << (RUNE_LIT - 64)) | (1L << (RAW_STRING_LIT - 64)) | (1L << (INTERPRETED_STRING_LIT - 64)))) != 0)) { + { + setState(969); + expression(0); + } + } + + setState(972); + match(COLON); + setState(974); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNC) | (1L << INTERFACE) | (1L << MAP) | (1L << STRUCT) | (1L << CHAN) | (1L << NIL_LIT) | (1L << IDENTIFIER) | (1L << L_PAREN) | (1L << L_BRACKET) | (1L << EXCLAMATION) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (RECEIVE - 64)) | (1L << (DECIMAL_LIT - 64)) | (1L << (BINARY_LIT - 64)) | (1L << (OCTAL_LIT - 64)) | (1L << (HEX_LIT - 64)) | (1L << (FLOAT_LIT - 64)) | (1L << (IMAGINARY_LIT - 64)) | (1L << (RUNE_LIT - 64)) | (1L << (RAW_STRING_LIT - 64)) | (1L << (INTERPRETED_STRING_LIT - 64)))) != 0)) { + { + setState(973); + expression(0); + } + } + + } + break; + case 2: + { + setState(977); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNC) | (1L << INTERFACE) | (1L << MAP) | (1L << STRUCT) | (1L << CHAN) | (1L << NIL_LIT) | (1L << IDENTIFIER) | (1L << L_PAREN) | (1L << L_BRACKET) | (1L << EXCLAMATION) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (RECEIVE - 64)) | (1L << (DECIMAL_LIT - 64)) | (1L << (BINARY_LIT - 64)) | (1L << (OCTAL_LIT - 64)) | (1L << (HEX_LIT - 64)) | (1L << (FLOAT_LIT - 64)) | (1L << (IMAGINARY_LIT - 64)) | (1L << (RUNE_LIT - 64)) | (1L << (RAW_STRING_LIT - 64)) | (1L << (INTERPRETED_STRING_LIT - 64)))) != 0)) { + { + setState(976); + expression(0); + } + } + + setState(979); + match(COLON); + setState(980); + expression(0); + setState(981); + match(COLON); + setState(982); + expression(0); + } + break; + } + setState(986); + match(R_BRACKET); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TypeAssertionContext extends ParserRuleContext { + public TerminalNode DOT() { return getToken(GoParser.DOT, 0); } + public TerminalNode L_PAREN() { return getToken(GoParser.L_PAREN, 0); } + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public TerminalNode R_PAREN() { return getToken(GoParser.R_PAREN, 0); } + public TypeAssertionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_typeAssertion; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterTypeAssertion(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitTypeAssertion(this); + } + } + + public final TypeAssertionContext typeAssertion() throws RecognitionException { + TypeAssertionContext _localctx = new TypeAssertionContext(_ctx, getState()); + enterRule(_localctx, 200, RULE_typeAssertion); + try { + enterOuterAlt(_localctx, 1); + { + setState(988); + match(DOT); + setState(989); + match(L_PAREN); + setState(990); + type_(); + setState(991); + match(R_PAREN); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ArgumentsContext extends ParserRuleContext { + public TerminalNode L_PAREN() { return getToken(GoParser.L_PAREN, 0); } + public TerminalNode R_PAREN() { return getToken(GoParser.R_PAREN, 0); } + public ExpressionListContext expressionList() { + return getRuleContext(ExpressionListContext.class,0); + } + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public TerminalNode ELLIPSIS() { return getToken(GoParser.ELLIPSIS, 0); } + public List COMMA() { return getTokens(GoParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(GoParser.COMMA, i); + } + public ArgumentsContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_arguments; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterArguments(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitArguments(this); + } + } + + public final ArgumentsContext arguments() throws RecognitionException { + ArgumentsContext _localctx = new ArgumentsContext(_ctx, getState()); + enterRule(_localctx, 202, RULE_arguments); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(993); + match(L_PAREN); + setState(1008); + _errHandler.sync(this); + _la = _input.LA(1); + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << FUNC) | (1L << INTERFACE) | (1L << MAP) | (1L << STRUCT) | (1L << CHAN) | (1L << NIL_LIT) | (1L << IDENTIFIER) | (1L << L_PAREN) | (1L << L_BRACKET) | (1L << EXCLAMATION) | (1L << PLUS) | (1L << MINUS) | (1L << CARET) | (1L << STAR) | (1L << AMPERSAND))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (RECEIVE - 64)) | (1L << (DECIMAL_LIT - 64)) | (1L << (BINARY_LIT - 64)) | (1L << (OCTAL_LIT - 64)) | (1L << (HEX_LIT - 64)) | (1L << (FLOAT_LIT - 64)) | (1L << (IMAGINARY_LIT - 64)) | (1L << (RUNE_LIT - 64)) | (1L << (RAW_STRING_LIT - 64)) | (1L << (INTERPRETED_STRING_LIT - 64)))) != 0)) { + { + setState(1000); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,116,_ctx) ) { + case 1: + { + setState(994); + expressionList(); + } + break; + case 2: + { + setState(995); + type_(); + setState(998); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,115,_ctx) ) { + case 1: + { + setState(996); + match(COMMA); + setState(997); + expressionList(); + } + break; + } + } + break; + } + setState(1003); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==ELLIPSIS) { + { + setState(1002); + match(ELLIPSIS); + } + } + + setState(1006); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==COMMA) { + { + setState(1005); + match(COMMA); + } + } + + } + } + + setState(1010); + match(R_PAREN); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class MethodExprContext extends ParserRuleContext { + public Type_Context type_() { + return getRuleContext(Type_Context.class,0); + } + public TerminalNode DOT() { return getToken(GoParser.DOT, 0); } + public TerminalNode IDENTIFIER() { return getToken(GoParser.IDENTIFIER, 0); } + public MethodExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_methodExpr; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterMethodExpr(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitMethodExpr(this); + } + } + + public final MethodExprContext methodExpr() throws RecognitionException { + MethodExprContext _localctx = new MethodExprContext(_ctx, getState()); + enterRule(_localctx, 204, RULE_methodExpr); + try { + enterOuterAlt(_localctx, 1); + { + setState(1012); + type_(); + setState(1013); + match(DOT); + setState(1014); + match(IDENTIFIER); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class EosContext extends ParserRuleContext { + public TerminalNode SEMI() { return getToken(GoParser.SEMI, 0); } + public TerminalNode EOF() { return getToken(GoParser.EOF, 0); } + public TerminalNode EOS() { return getToken(GoParser.EOS, 0); } + public EosContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_eos; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).enterEos(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof GoParserListener) ((GoParserListener)listener).exitEos(this); + } + } + + public final EosContext eos() throws RecognitionException { + EosContext _localctx = new EosContext(_ctx, getState()); + enterRule(_localctx, 206, RULE_eos); + try { + setState(1020); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,120,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(1016); + match(SEMI); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(1017); + match(EOF); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(1018); + match(EOS); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(1019); + if (!(this.closingBracket())) throw new FailedPredicateException(this, "this.closingBracket()"); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 25: + return statementList_sempred((StatementListContext)_localctx, predIndex); + case 77: + return expression_sempred((ExpressionContext)_localctx, predIndex); + case 78: + return primaryExpr_sempred((PrimaryExprContext)_localctx, predIndex); + case 103: + return eos_sempred((EosContext)_localctx, predIndex); + } + return true; + } + private boolean statementList_sempred(StatementListContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return this.closingBracket(); + } + return true; + } + private boolean expression_sempred(ExpressionContext _localctx, int predIndex) { + switch (predIndex) { + case 1: + return precpred(_ctx, 5); + case 2: + return precpred(_ctx, 4); + case 3: + return precpred(_ctx, 3); + case 4: + return precpred(_ctx, 2); + case 5: + return precpred(_ctx, 1); + } + return true; + } + private boolean primaryExpr_sempred(PrimaryExprContext _localctx, int predIndex) { + switch (predIndex) { + case 6: + return precpred(_ctx, 1); + } + return true; + } + private boolean eos_sempred(EosContext _localctx, int predIndex) { + switch (predIndex) { + case 7: + return this.closingBracket(); + } + return true; + } + + public static final String _serializedATN = + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\\\u0401\4\2\t\2\4"+ + "\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+ + "\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+ + "\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+ + "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ + "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+ + ",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+ + "\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+ + "\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+ + "\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+ + "\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+ + "`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\3\2\3\2\3\2"+ + "\3\2\3\2\7\2\u00d8\n\2\f\2\16\2\u00db\13\2\3\2\3\2\3\2\5\2\u00e0\n\2\3"+ + "\2\3\2\7\2\u00e4\n\2\f\2\16\2\u00e7\13\2\3\2\3\2\3\3\3\3\3\3\3\4\3\4\3"+ + "\4\3\4\3\4\3\4\7\4\u00f4\n\4\f\4\16\4\u00f7\13\4\3\4\5\4\u00fa\n\4\3\5"+ + "\5\5\u00fd\n\5\3\5\3\5\3\6\3\6\3\7\3\7\3\7\5\7\u0106\n\7\3\b\3\b\3\b\3"+ + "\b\3\b\3\b\7\b\u010e\n\b\f\b\16\b\u0111\13\b\3\b\5\b\u0114\n\b\3\t\3\t"+ + "\5\t\u0118\n\t\3\t\3\t\5\t\u011c\n\t\3\n\3\n\3\n\7\n\u0121\n\n\f\n\16"+ + "\n\u0124\13\n\3\13\3\13\3\13\7\13\u0129\n\13\f\13\16\13\u012c\13\13\3"+ + "\f\3\f\3\r\7\r\u0131\n\r\f\r\16\r\u0134\13\r\3\r\3\r\3\r\3\r\3\r\3\r\7"+ + "\r\u013c\n\r\f\r\16\r\u013f\13\r\3\r\5\r\u0142\n\r\3\16\3\16\5\16\u0146"+ + "\n\16\3\17\3\17\3\17\3\17\3\20\3\20\5\20\u014e\n\20\3\20\3\20\3\21\3\21"+ + "\3\21\3\21\7\21\u0156\n\21\f\21\16\21\u0159\13\21\3\21\3\21\3\22\3\22"+ + "\3\22\3\23\3\23\3\23\7\23\u0163\n\23\f\23\16\23\u0166\13\23\3\24\5\24"+ + "\u0169\n\24\3\24\3\24\3\25\3\25\3\25\5\25\u0170\n\25\3\25\3\25\5\25\u0174"+ + "\n\25\3\26\3\26\3\26\3\26\3\26\5\26\u017b\n\26\3\27\3\27\3\30\3\30\3\30"+ + "\3\30\3\30\3\30\7\30\u0185\n\30\f\30\16\30\u0188\13\30\3\30\5\30\u018b"+ + "\n\30\3\31\3\31\3\31\3\31\5\31\u0191\n\31\3\31\3\31\5\31\u0195\n\31\3"+ + "\32\3\32\5\32\u0199\n\32\3\32\3\32\3\33\5\33\u019e\n\33\3\33\5\33\u01a1"+ + "\n\33\3\33\5\33\u01a4\n\33\3\33\3\33\3\33\6\33\u01a9\n\33\r\33\16\33\u01aa"+ + "\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34"+ + "\3\34\5\34\u01bc\n\34\3\35\3\35\3\35\3\35\3\35\5\35\u01c3\n\35\3\36\3"+ + "\36\3\37\3\37\3\37\3\37\3 \3 \3 \3!\3!\3!\3!\3\"\5\"\u01d3\n\"\3\"\3\""+ + "\3#\3#\3#\3#\3$\3$\3$\5$\u01de\n$\3%\3%\5%\u01e2\n%\3&\3&\5&\u01e6\n&"+ + "\3\'\3\'\5\'\u01ea\n\'\3(\3(\3(\3)\3)\3*\3*\3*\3+\3+\3+\3+\3+\3+\3+\3"+ + "+\3+\5+\u01fd\n+\3+\3+\3+\3+\5+\u0203\n+\5+\u0205\n+\3,\3,\5,\u0209\n"+ + ",\3-\3-\5-\u020d\n-\3-\5-\u0210\n-\3-\3-\5-\u0214\n-\5-\u0216\n-\3-\3"+ + "-\7-\u021a\n-\f-\16-\u021d\13-\3-\3-\3.\3.\3.\5.\u0224\n.\3/\3/\3/\5/"+ + "\u0229\n/\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\5\60\u0234\n\60"+ + "\3\60\3\60\7\60\u0238\n\60\f\60\16\60\u023b\13\60\3\60\3\60\3\61\3\61"+ + "\5\61\u0241\n\61\3\61\3\61\3\61\3\61\3\61\3\61\3\62\3\62\3\62\5\62\u024c"+ + "\n\62\3\63\3\63\3\63\5\63\u0251\n\63\3\64\3\64\5\64\u0255\n\64\3\64\3"+ + "\64\3\64\5\64\u025a\n\64\7\64\u025c\n\64\f\64\16\64\u025f\13\64\3\65\3"+ + "\65\3\65\7\65\u0264\n\65\f\65\16\65\u0267\13\65\3\65\3\65\3\66\3\66\3"+ + "\66\5\66\u026e\n\66\3\67\3\67\3\67\5\67\u0273\n\67\3\67\5\67\u0276\n\67"+ + "\38\38\38\38\38\38\58\u027e\n8\38\38\39\39\59\u0284\n9\39\39\59\u0288"+ + "\n9\59\u028a\n9\39\39\3:\5:\u028f\n:\3:\3:\5:\u0293\n:\3:\3:\5:\u0297"+ + "\n:\3;\3;\3;\3;\3;\3;\5;\u029f\n;\3;\3;\3;\3<\3<\3<\3=\3=\5=\u02a9\n="+ + "\3=\3=\3=\3=\3=\5=\u02b0\n=\3>\3>\3>\5>\u02b5\n>\3>\3>\3?\3?\5?\u02bb"+ + "\n?\3@\3@\3@\3@\3@\3@\3@\3@\5@\u02c5\n@\3A\3A\3A\3A\3A\3B\3B\3C\3C\3D"+ + "\3D\3D\3E\3E\3E\3E\5E\u02d7\nE\3E\3E\7E\u02db\nE\fE\16E\u02de\13E\3E\3"+ + "E\3F\3F\3F\3F\3G\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\5H\u02f1\nH\3H\3H\3I\3"+ + "I\3I\3I\3I\3I\5I\u02fb\nI\3J\3J\3J\3K\3K\5K\u0302\nK\3L\3L\5L\u0306\n"+ + "L\3M\3M\3M\3M\7M\u030c\nM\fM\16M\u030f\13M\3M\5M\u0312\nM\5M\u0314\nM"+ + "\3M\3M\3N\5N\u0319\nN\3N\5N\u031c\nN\3N\3N\3O\3O\3O\3O\5O\u0324\nO\3O"+ + "\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\7O\u0335\nO\fO\16O\u0338\13"+ + "O\3P\3P\3P\3P\5P\u033e\nP\3P\3P\3P\3P\3P\3P\3P\5P\u0347\nP\7P\u0349\n"+ + "P\fP\16P\u034c\13P\3Q\3Q\3Q\3Q\5Q\u0352\nQ\3Q\3Q\3R\3R\3R\5R\u0359\nR"+ + "\3R\3R\3R\3R\5R\u035f\nR\3S\3S\3S\5S\u0364\nS\3T\3T\3T\3T\5T\u036a\nT"+ + "\3U\3U\3V\3V\3W\3W\3W\3W\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Y\5Y\u0381"+ + "\nY\5Y\u0383\nY\3Z\3Z\3Z\5Z\u0388\nZ\5Z\u038a\nZ\3Z\3Z\3[\3[\3[\7[\u0391"+ + "\n[\f[\16[\u0394\13[\3\\\3\\\3\\\5\\\u0399\n\\\3\\\3\\\3]\3]\5]\u039f"+ + "\n]\3^\3^\5^\u03a3\n^\3_\3_\3_\3_\3_\7_\u03aa\n_\f_\16_\u03ad\13_\3_\3"+ + "_\3`\3`\3`\3`\5`\u03b5\n`\3`\5`\u03b8\n`\3a\3a\3b\5b\u03bd\nb\3b\3b\5"+ + "b\u03c1\nb\3c\3c\3c\3c\3d\3d\3d\3d\3e\3e\5e\u03cd\ne\3e\3e\5e\u03d1\n"+ + "e\3e\5e\u03d4\ne\3e\3e\3e\3e\3e\5e\u03db\ne\3e\3e\3f\3f\3f\3f\3f\3g\3"+ + "g\3g\3g\3g\5g\u03e9\ng\5g\u03eb\ng\3g\5g\u03ee\ng\3g\5g\u03f1\ng\5g\u03f3"+ + "\ng\3g\3g\3h\3h\3h\3h\3i\3i\3i\3i\5i\u03ff\ni\3i\2\4\u009c\u009ej\2\4"+ + "\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNP"+ + "RTVXZ\\^`bdfhjlnprtvxz|~\u0080\u0082\u0084\u0086\u0088\u008a\u008c\u008e"+ + "\u0090\u0092\u0094\u0096\u0098\u009a\u009c\u009e\u00a0\u00a2\u00a4\u00a6"+ + "\u00a8\u00aa\u00ac\u00ae\u00b0\u00b2\u00b4\u00b6\u00b8\u00ba\u00bc\u00be"+ + "\u00c0\u00c2\u00c4\u00c6\u00c8\u00ca\u00cc\u00ce\u00d0\2\f\4\2\35\35("+ + "(\4\2TTVV\3\2)*\4\2\65:=A\3\2\u01ca\3\2\2\2@\u01cd\3\2\2\2B\u01d2\3\2\2\2D\u01d6\3\2\2\2F\u01da"+ + "\3\2\2\2H\u01df\3\2\2\2J\u01e3\3\2\2\2L\u01e7\3\2\2\2N\u01eb\3\2\2\2P"+ + "\u01ee\3\2\2\2R\u01f0\3\2\2\2T\u01f3\3\2\2\2V\u0208\3\2\2\2X\u020a\3\2"+ + "\2\2Z\u0220\3\2\2\2\\\u0228\3\2\2\2^\u022a\3\2\2\2`\u0240\3\2\2\2b\u0248"+ + "\3\2\2\2d\u0250\3\2\2\2f\u0254\3\2\2\2h\u0260\3\2\2\2j\u026a\3\2\2\2l"+ + "\u0275\3\2\2\2n\u027d\3\2\2\2p\u0281\3\2\2\2r\u028e\3\2\2\2t\u029e\3\2"+ + "\2\2v\u02a3\3\2\2\2x\u02af\3\2\2\2z\u02b1\3\2\2\2|\u02ba\3\2\2\2~\u02c4"+ + "\3\2\2\2\u0080\u02c6\3\2\2\2\u0082\u02cb\3\2\2\2\u0084\u02cd\3\2\2\2\u0086"+ + "\u02cf\3\2\2\2\u0088\u02d2\3\2\2\2\u008a\u02e1\3\2\2\2\u008c\u02e5\3\2"+ + "\2\2\u008e\u02f0\3\2\2\2\u0090\u02fa\3\2\2\2\u0092\u02fc\3\2\2\2\u0094"+ + "\u02ff\3\2\2\2\u0096\u0305\3\2\2\2\u0098\u0307\3\2\2\2\u009a\u0318\3\2"+ + "\2\2\u009c\u0323\3\2\2\2\u009e\u033d\3\2\2\2\u00a0\u034d\3\2\2\2\u00a2"+ + "\u035e\3\2\2\2\u00a4\u0363\3\2\2\2\u00a6\u0369\3\2\2\2\u00a8\u036b\3\2"+ + "\2\2\u00aa\u036d\3\2\2\2\u00ac\u036f\3\2\2\2\u00ae\u0373\3\2\2\2\u00b0"+ + "\u0382\3\2\2\2\u00b2\u0384\3\2\2\2\u00b4\u038d\3\2\2\2\u00b6\u0398\3\2"+ + "\2\2\u00b8\u039e\3\2\2\2\u00ba\u03a2\3\2\2\2\u00bc\u03a4\3\2\2\2\u00be"+ + "\u03b4\3\2\2\2\u00c0\u03b9\3\2\2\2\u00c2\u03bc\3\2\2\2\u00c4\u03c2\3\2"+ + "\2\2\u00c6\u03c6\3\2\2\2\u00c8\u03ca\3\2\2\2\u00ca\u03de\3\2\2\2\u00cc"+ + "\u03e3\3\2\2\2\u00ce\u03f6\3\2\2\2\u00d0\u03fe\3\2\2\2\u00d2\u00d3\5\4"+ + "\3\2\u00d3\u00d9\5\u00d0i\2\u00d4\u00d5\5\6\4\2\u00d5\u00d6\5\u00d0i\2"+ + "\u00d6\u00d8\3\2\2\2\u00d7\u00d4\3\2\2\2\u00d8\u00db\3\2\2\2\u00d9\u00d7"+ + "\3\2\2\2\u00d9\u00da\3\2\2\2\u00da\u00e5\3\2\2\2\u00db\u00d9\3\2\2\2\u00dc"+ + "\u00e0\5(\25\2\u00dd\u00e0\5*\26\2\u00de\u00e0\5\f\7\2\u00df\u00dc\3\2"+ + "\2\2\u00df\u00dd\3\2\2\2\u00df\u00de\3\2\2\2\u00e0\u00e1\3\2\2\2\u00e1"+ + "\u00e2\5\u00d0i\2\u00e2\u00e4\3\2\2\2\u00e3\u00df\3\2\2\2\u00e4\u00e7"+ + "\3\2\2\2\u00e5\u00e3\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e6\u00e8\3\2\2\2\u00e7"+ + "\u00e5\3\2\2\2\u00e8\u00e9\7\2\2\3\u00e9\3\3\2\2\2\u00ea\u00eb\7\20\2"+ + "\2\u00eb\u00ec\7\35\2\2\u00ec\5\3\2\2\2\u00ed\u00f9\7\31\2\2\u00ee\u00fa"+ + "\5\b\5\2\u00ef\u00f5\7\36\2\2\u00f0\u00f1\5\b\5\2\u00f1\u00f2\5\u00d0"+ + "i\2\u00f2\u00f4\3\2\2\2\u00f3\u00f0\3\2\2\2\u00f4\u00f7\3\2\2\2\u00f5"+ + "\u00f3\3\2\2\2\u00f5\u00f6\3\2\2\2\u00f6\u00f8\3\2\2\2\u00f7\u00f5\3\2"+ + "\2\2\u00f8\u00fa\7\37\2\2\u00f9\u00ee\3\2\2\2\u00f9\u00ef\3\2\2\2\u00fa"+ + "\7\3\2\2\2\u00fb\u00fd\t\2\2\2\u00fc\u00fb\3\2\2\2\u00fc\u00fd\3\2\2\2"+ + "\u00fd\u00fe\3\2\2\2\u00fe\u00ff\5\n\6\2\u00ff\t\3\2\2\2\u0100\u0101\5"+ + "\u00c0a\2\u0101\13\3\2\2\2\u0102\u0106\5\16\b\2\u0103\u0106\5\30\r\2\u0104"+ + "\u0106\5.\30\2\u0105\u0102\3\2\2\2\u0105\u0103\3\2\2\2\u0105\u0104\3\2"+ + "\2\2\u0106\r\3\2\2\2\u0107\u0113\7\22\2\2\u0108\u0114\5\20\t\2\u0109\u010f"+ + "\7\36\2\2\u010a\u010b\5\20\t\2\u010b\u010c\5\u00d0i\2\u010c\u010e\3\2"+ + "\2\2\u010d\u010a\3\2\2\2\u010e\u0111\3\2\2\2\u010f\u010d\3\2\2\2\u010f"+ + "\u0110\3\2\2\2\u0110\u0112\3\2\2\2\u0111\u010f\3\2\2\2\u0112\u0114\7\37"+ + "\2\2\u0113\u0108\3\2\2\2\u0113\u0109\3\2\2\2\u0114\17\3\2\2\2\u0115\u011b"+ + "\5\22\n\2\u0116\u0118\5x=\2\u0117\u0116\3\2\2\2\u0117\u0118\3\2\2\2\u0118"+ + "\u0119\3\2\2\2\u0119\u011a\7$\2\2\u011a\u011c\5\24\13\2\u011b\u0117\3"+ + "\2\2\2\u011b\u011c\3\2\2\2\u011c\21\3\2\2\2\u011d\u0122\7\35\2\2\u011e"+ + "\u011f\7%\2\2\u011f\u0121\7\35\2\2\u0120\u011e\3\2\2\2\u0121\u0124\3\2"+ + "\2\2\u0122\u0120\3\2\2\2\u0122\u0123\3\2\2\2\u0123\23\3\2\2\2\u0124\u0122"+ + "\3\2\2\2\u0125\u012a\5\u009cO\2\u0126\u0127\7%\2\2\u0127\u0129\5\u009c"+ + "O\2\u0128\u0126\3\2\2\2\u0129\u012c\3\2\2\2\u012a\u0128\3\2\2\2\u012a"+ + "\u012b\3\2\2\2\u012b\25\3\2\2\2\u012c\u012a\3\2\2\2\u012d\u012e\t\3\2"+ + "\2\u012e\27\3\2\2\2\u012f\u0131\5\26\f\2\u0130\u012f\3\2\2\2\u0131\u0134"+ + "\3\2\2\2\u0132\u0130\3\2\2\2\u0132\u0133\3\2\2\2\u0133\u0135\3\2\2\2\u0134"+ + "\u0132\3\2\2\2\u0135\u0141\7\26\2\2\u0136\u0142\5\32\16\2\u0137\u013d"+ + "\7\36\2\2\u0138\u0139\5\32\16\2\u0139\u013a\5\u00d0i\2\u013a\u013c\3\2"+ + "\2\2\u013b\u0138\3\2\2\2\u013c\u013f\3\2\2\2\u013d\u013b\3\2\2\2\u013d"+ + "\u013e\3\2\2\2\u013e\u0140\3\2\2\2\u013f\u013d\3\2\2\2\u0140\u0142\7\37"+ + "\2\2\u0141\u0136\3\2\2\2\u0141\u0137\3\2\2\2\u0142\31\3\2\2\2\u0143\u0146"+ + "\5\34\17\2\u0144\u0146\5\36\20\2\u0145\u0143\3\2\2\2\u0145\u0144\3\2\2"+ + "\2\u0146\33\3\2\2\2\u0147\u0148\7\35\2\2\u0148\u0149\7$\2\2\u0149\u014a"+ + "\5x=\2\u014a\35\3\2\2\2\u014b\u014d\7\35\2\2\u014c\u014e\5 \21\2\u014d"+ + "\u014c\3\2\2\2\u014d\u014e\3\2\2\2\u014e\u014f\3\2\2\2\u014f\u0150\5x"+ + "=\2\u0150\37\3\2\2\2\u0151\u0152\7\"\2\2\u0152\u0157\5\"\22\2\u0153\u0154"+ + "\7%\2\2\u0154\u0156\5\"\22\2\u0155\u0153\3\2\2\2\u0156\u0159\3\2\2\2\u0157"+ + "\u0155\3\2\2\2\u0157\u0158\3\2\2\2\u0158\u015a\3\2\2\2\u0159\u0157\3\2"+ + "\2\2\u015a\u015b\7#\2\2\u015b!\3\2\2\2\u015c\u015d\5\22\n\2\u015d\u015e"+ + "\5$\23\2\u015e#\3\2\2\2\u015f\u0164\5&\24\2\u0160\u0161\7\65\2\2\u0161"+ + "\u0163\5&\24\2\u0162\u0160\3\2\2\2\u0163\u0166\3\2\2\2\u0164\u0162\3\2"+ + "\2\2\u0164\u0165\3\2\2\2\u0165%\3\2\2\2\u0166\u0164\3\2\2\2\u0167\u0169"+ + "\7;\2\2\u0168\u0167\3\2\2\2\u0168\u0169\3\2\2\2\u0169\u016a\3\2\2\2\u016a"+ + "\u016b\5x=\2\u016b\'\3\2\2\2\u016c\u016d\7\5\2\2\u016d\u016f\7\35\2\2"+ + "\u016e\u0170\5 \21\2\u016f\u016e\3\2\2\2\u016f\u0170\3\2\2\2\u0170\u0171"+ + "\3\2\2\2\u0171\u0173\5\u0094K\2\u0172\u0174\5\62\32\2\u0173\u0172\3\2"+ + "\2\2\u0173\u0174\3\2\2\2\u0174)\3\2\2\2\u0175\u0176\7\5\2\2\u0176\u0177"+ + "\5,\27\2\u0177\u0178\7\35\2\2\u0178\u017a\5\u0094K\2\u0179\u017b\5\62"+ + "\32\2\u017a\u0179\3\2\2\2\u017a\u017b\3\2\2\2\u017b+\3\2\2\2\u017c\u017d"+ + "\5\u0098M\2\u017d-\3\2\2\2\u017e\u018a\7\33\2\2\u017f\u018b\5\60\31\2"+ + "\u0180\u0186\7\36\2\2\u0181\u0182\5\60\31\2\u0182\u0183\5\u00d0i\2\u0183"+ + "\u0185\3\2\2\2\u0184\u0181\3\2\2\2\u0185\u0188\3\2\2\2\u0186\u0184\3\2"+ + "\2\2\u0186\u0187\3\2\2\2\u0187\u0189\3\2\2\2\u0188\u0186\3\2\2\2\u0189"+ + "\u018b\7\37\2\2\u018a\u017f\3\2\2\2\u018a\u0180\3\2\2\2\u018b/\3\2\2\2"+ + "\u018c\u0194\5\22\n\2\u018d\u0190\5x=\2\u018e\u018f\7$\2\2\u018f\u0191"+ + "\5\24\13\2\u0190\u018e\3\2\2\2\u0190\u0191\3\2\2\2\u0191\u0195\3\2\2\2"+ + "\u0192\u0193\7$\2\2\u0193\u0195\5\24\13\2\u0194\u018d\3\2\2\2\u0194\u0192"+ + "\3\2\2\2\u0195\61\3\2\2\2\u0196\u0198\7 \2\2\u0197\u0199\5\64\33\2\u0198"+ + "\u0197\3\2\2\2\u0198\u0199\3\2\2\2\u0199\u019a\3\2\2\2\u019a\u019b\7!"+ + "\2\2\u019b\63\3\2\2\2\u019c\u019e\7&\2\2\u019d\u019c\3\2\2\2\u019d\u019e"+ + "\3\2\2\2\u019e\u01a4\3\2\2\2\u019f\u01a1\7[\2\2\u01a0\u019f\3\2\2\2\u01a0"+ + "\u01a1\3\2\2\2\u01a1\u01a4\3\2\2\2\u01a2\u01a4\6\33\2\2\u01a3\u019d\3"+ + "\2\2\2\u01a3\u01a0\3\2\2\2\u01a3\u01a2\3\2\2\2\u01a4\u01a5\3\2\2\2\u01a5"+ + "\u01a6\5\66\34\2\u01a6\u01a7\5\u00d0i\2\u01a7\u01a9\3\2\2\2\u01a8\u01a3"+ + "\3\2\2\2\u01a9\u01aa\3\2\2\2\u01aa\u01a8\3\2\2\2\u01aa\u01ab\3\2\2\2\u01ab"+ + "\65\3\2\2\2\u01ac\u01bc\5\f\7\2\u01ad\u01bc\5F$\2\u01ae\u01bc\58\35\2"+ + "\u01af\u01bc\5v<\2\u01b0\u01bc\5H%\2\u01b1\u01bc\5J&\2\u01b2\u01bc\5L"+ + "\'\2\u01b3\u01bc\5N(\2\u01b4\u01bc\5P)\2\u01b5\u01bc\5\62\32\2\u01b6\u01bc"+ + "\5T+\2\u01b7\u01bc\5V,\2\u01b8\u01bc\5h\65\2\u01b9\u01bc\5p9\2\u01ba\u01bc"+ + "\5R*\2\u01bb\u01ac\3\2\2\2\u01bb\u01ad\3\2\2\2\u01bb\u01ae\3\2\2\2\u01bb"+ + "\u01af\3\2\2\2\u01bb\u01b0\3\2\2\2\u01bb\u01b1\3\2\2\2\u01bb\u01b2\3\2"+ + "\2\2\u01bb\u01b3\3\2\2\2\u01bb\u01b4\3\2\2\2\u01bb\u01b5\3\2\2\2\u01bb"+ + "\u01b6\3\2\2\2\u01bb\u01b7\3\2\2\2\u01bb\u01b8\3\2\2\2\u01bb\u01b9\3\2"+ + "\2\2\u01bb\u01ba\3\2\2\2\u01bc\67\3\2\2\2\u01bd\u01c3\5<\37\2\u01be\u01c3"+ + "\5> \2\u01bf\u01c3\5@!\2\u01c0\u01c3\5:\36\2\u01c1\u01c3\5D#\2\u01c2\u01bd"+ + "\3\2\2\2\u01c2\u01be\3\2\2\2\u01c2\u01bf\3\2\2\2\u01c2\u01c0\3\2\2\2\u01c2"+ + "\u01c1\3\2\2\2\u01c39\3\2\2\2\u01c4\u01c5\5\u009cO\2\u01c5;\3\2\2\2\u01c6"+ + "\u01c7\5\u009cO\2\u01c7\u01c8\7B\2\2\u01c8\u01c9\5\u009cO\2\u01c9=\3\2"+ + "\2\2\u01ca\u01cb\5\u009cO\2\u01cb\u01cc\t\4\2\2\u01cc?\3\2\2\2\u01cd\u01ce"+ + "\5\24\13\2\u01ce\u01cf\5B\"\2\u01cf\u01d0\5\24\13\2\u01d0A\3\2\2\2\u01d1"+ + "\u01d3\t\5\2\2\u01d2\u01d1\3\2\2\2\u01d2\u01d3\3\2\2\2\u01d3\u01d4\3\2"+ + "\2\2\u01d4\u01d5\7$\2\2\u01d5C\3\2\2\2\u01d6\u01d7\5\22\n\2\u01d7\u01d8"+ + "\7+\2\2\u01d8\u01d9\5\24\13\2\u01d9E\3\2\2\2\u01da\u01db\7\35\2\2\u01db"+ + "\u01dd\7\'\2\2\u01dc\u01de\5\66\34\2\u01dd\u01dc\3\2\2\2\u01dd\u01de\3"+ + "\2\2\2\u01deG\3\2\2\2\u01df\u01e1\7\32\2\2\u01e0\u01e2\5\24\13\2\u01e1"+ + "\u01e0\3\2\2\2\u01e1\u01e2\3\2\2\2\u01e2I\3\2\2\2\u01e3\u01e5\7\3\2\2"+ + "\u01e4\u01e6\7\35\2\2\u01e5\u01e4\3\2\2\2\u01e5\u01e6\3\2\2\2\u01e6K\3"+ + "\2\2\2\u01e7\u01e9\7\27\2\2\u01e8\u01ea\7\35\2\2\u01e9\u01e8\3\2\2\2\u01e9"+ + "\u01ea\3\2\2\2\u01eaM\3\2\2\2\u01eb\u01ec\7\17\2\2\u01ec\u01ed\7\35\2"+ + "\2\u01edO\3\2\2\2\u01ee\u01ef\7\23\2\2\u01efQ\3\2\2\2\u01f0\u01f1\7\t"+ + "\2\2\u01f1\u01f2\5\u009cO\2\u01f2S\3\2\2\2\u01f3\u01fc\7\24\2\2\u01f4"+ + "\u01fd\5\u009cO\2\u01f5\u01f6\5\u00d0i\2\u01f6\u01f7\5\u009cO\2\u01f7"+ + "\u01fd\3\2\2\2\u01f8\u01f9\58\35\2\u01f9\u01fa\5\u00d0i\2\u01fa\u01fb"+ + "\5\u009cO\2\u01fb\u01fd\3\2\2\2\u01fc\u01f4\3\2\2\2\u01fc\u01f5\3\2\2"+ + "\2\u01fc\u01f8\3\2\2\2\u01fd\u01fe\3\2\2\2\u01fe\u0204\5\62\32\2\u01ff"+ + "\u0202\7\16\2\2\u0200\u0203\5T+\2\u0201\u0203\5\62\32\2\u0202\u0200\3"+ + "\2\2\2\u0202\u0201\3\2\2\2\u0203\u0205\3\2\2\2\u0204\u01ff\3\2\2\2\u0204"+ + "\u0205\3\2\2\2\u0205U\3\2\2\2\u0206\u0209\5X-\2\u0207\u0209\5^\60\2\u0208"+ + "\u0206\3\2\2\2\u0208\u0207\3\2\2\2\u0209W\3\2\2\2\u020a\u0215\7\21\2\2"+ + "\u020b\u020d\5\u009cO\2\u020c\u020b\3\2\2\2\u020c\u020d\3\2\2\2\u020d"+ + "\u0216\3\2\2\2\u020e\u0210\58\35\2\u020f\u020e\3\2\2\2\u020f\u0210\3\2"+ + "\2\2\u0210\u0211\3\2\2\2\u0211\u0213\5\u00d0i\2\u0212\u0214\5\u009cO\2"+ + "\u0213\u0212\3\2\2\2\u0213\u0214\3\2\2\2\u0214\u0216\3\2\2\2\u0215\u020c"+ + "\3\2\2\2\u0215\u020f\3\2\2\2\u0216\u0217\3\2\2\2\u0217\u021b\7 \2\2\u0218"+ + "\u021a\5Z.\2\u0219\u0218\3\2\2\2\u021a\u021d\3\2\2\2\u021b\u0219\3\2\2"+ + "\2\u021b\u021c\3\2\2\2\u021c\u021e\3\2\2\2\u021d\u021b\3\2\2\2\u021e\u021f"+ + "\7!\2\2\u021fY\3\2\2\2\u0220\u0221\5\\/\2\u0221\u0223\7\'\2\2\u0222\u0224"+ + "\5\64\33\2\u0223\u0222\3\2\2\2\u0223\u0224\3\2\2\2\u0224[\3\2\2\2\u0225"+ + "\u0226\7\b\2\2\u0226\u0229\5\24\13\2\u0227\u0229\7\4\2\2\u0228\u0225\3"+ + "\2\2\2\u0228\u0227\3\2\2\2\u0229]\3\2\2\2\u022a\u0233\7\21\2\2\u022b\u0234"+ + "\5`\61\2\u022c\u022d\5\u00d0i\2\u022d\u022e\5`\61\2\u022e\u0234\3\2\2"+ + "\2\u022f\u0230\58\35\2\u0230\u0231\5\u00d0i\2\u0231\u0232\5`\61\2\u0232"+ + "\u0234\3\2\2\2\u0233\u022b\3\2\2\2\u0233\u022c\3\2\2\2\u0233\u022f\3\2"+ + "\2\2\u0234\u0235\3\2\2\2\u0235\u0239\7 \2\2\u0236\u0238\5b\62\2\u0237"+ + "\u0236\3\2\2\2\u0238\u023b\3\2\2\2\u0239\u0237\3\2\2\2\u0239\u023a\3\2"+ + "\2\2\u023a\u023c\3\2\2\2\u023b\u0239\3\2\2\2\u023c\u023d\7!\2\2\u023d"+ + "_\3\2\2\2\u023e\u023f\7\35\2\2\u023f\u0241\7+\2\2\u0240\u023e\3\2\2\2"+ + "\u0240\u0241\3\2\2\2\u0241\u0242\3\2\2\2\u0242\u0243\5\u009eP\2\u0243"+ + "\u0244\7(\2\2\u0244\u0245\7\36\2\2\u0245\u0246\7\26\2\2\u0246\u0247\7"+ + "\37\2\2\u0247a\3\2\2\2\u0248\u0249\5d\63\2\u0249\u024b\7\'\2\2\u024a\u024c"+ + "\5\64\33\2\u024b\u024a\3\2\2\2\u024b\u024c\3\2\2\2\u024cc\3\2\2\2\u024d"+ + "\u024e\7\b\2\2\u024e\u0251\5f\64\2\u024f\u0251\7\4\2\2\u0250\u024d\3\2"+ + "\2\2\u0250\u024f\3\2\2\2\u0251e\3\2\2\2\u0252\u0255\5x=\2\u0253\u0255"+ + "\7\34\2\2\u0254\u0252\3\2\2\2\u0254\u0253\3\2\2\2\u0255\u025d\3\2\2\2"+ + "\u0256\u0259\7%\2\2\u0257\u025a\5x=\2\u0258\u025a\7\34\2\2\u0259\u0257"+ + "\3\2\2\2\u0259\u0258\3\2\2\2\u025a\u025c\3\2\2\2\u025b\u0256\3\2\2\2\u025c"+ + "\u025f\3\2\2\2\u025d\u025b\3\2\2\2\u025d\u025e\3\2\2\2\u025eg\3\2\2\2"+ + "\u025f\u025d\3\2\2\2\u0260\u0261\7\7\2\2\u0261\u0265\7 \2\2\u0262\u0264"+ + "\5j\66\2\u0263\u0262\3\2\2\2\u0264\u0267\3\2\2\2\u0265\u0263\3\2\2\2\u0265"+ + "\u0266\3\2\2\2\u0266\u0268\3\2\2\2\u0267\u0265\3\2\2\2\u0268\u0269\7!"+ + "\2\2\u0269i\3\2\2\2\u026a\u026b\5l\67\2\u026b\u026d\7\'\2\2\u026c\u026e"+ + "\5\64\33\2\u026d\u026c\3\2\2\2\u026d\u026e\3\2\2\2\u026ek\3\2\2\2\u026f"+ + "\u0272\7\b\2\2\u0270\u0273\5<\37\2\u0271\u0273\5n8\2\u0272\u0270\3\2\2"+ + "\2\u0272\u0271\3\2\2\2\u0273\u0276\3\2\2\2\u0274\u0276\7\4\2\2\u0275\u026f"+ + "\3\2\2\2\u0275\u0274\3\2\2\2\u0276m\3\2\2\2\u0277\u0278\5\24\13\2\u0278"+ + "\u0279\7$\2\2\u0279\u027e\3\2\2\2\u027a\u027b\5\22\n\2\u027b\u027c\7+"+ + "\2\2\u027c\u027e\3\2\2\2\u027d\u0277\3\2\2\2\u027d\u027a\3\2\2\2\u027d"+ + "\u027e\3\2\2\2\u027e\u027f\3\2\2\2\u027f\u0280\5\u009cO\2\u0280o\3\2\2"+ + "\2\u0281\u0289\7\30\2\2\u0282\u0284\5\u009cO\2\u0283\u0282\3\2\2\2\u0283"+ + "\u0284\3\2\2\2\u0284\u028a\3\2\2\2\u0285\u028a\5r:\2\u0286\u0288\5t;\2"+ + "\u0287\u0286\3\2\2\2\u0287\u0288\3\2\2\2\u0288\u028a\3\2\2\2\u0289\u0283"+ + "\3\2\2\2\u0289\u0285\3\2\2\2\u0289\u0287\3\2\2\2\u028a\u028b\3\2\2\2\u028b"+ + "\u028c\5\62\32\2\u028cq\3\2\2\2\u028d\u028f\58\35\2\u028e\u028d\3\2\2"+ + "\2\u028e\u028f\3\2\2\2\u028f\u0290\3\2\2\2\u0290\u0292\5\u00d0i\2\u0291"+ + "\u0293\5\u009cO\2\u0292\u0291\3\2\2\2\u0292\u0293\3\2\2\2\u0293\u0294"+ + "\3\2\2\2\u0294\u0296\5\u00d0i\2\u0295\u0297\58\35\2\u0296\u0295\3\2\2"+ + "\2\u0296\u0297\3\2\2\2\u0297s\3\2\2\2\u0298\u0299\5\24\13\2\u0299\u029a"+ + "\7$\2\2\u029a\u029f\3\2\2\2\u029b\u029c\5\22\n\2\u029c\u029d\7+\2\2\u029d"+ + "\u029f\3\2\2\2\u029e\u0298\3\2\2\2\u029e\u029b\3\2\2\2\u029e\u029f\3\2"+ + "\2\2\u029f\u02a0\3\2\2\2\u02a0\u02a1\7\25\2\2\u02a1\u02a2\5\u009cO\2\u02a2"+ + "u\3\2\2\2\u02a3\u02a4\7\n\2\2\u02a4\u02a5\5\u009cO\2\u02a5w\3\2\2\2\u02a6"+ + "\u02a8\5|?\2\u02a7\u02a9\5z>\2\u02a8\u02a7\3\2\2\2\u02a8\u02a9\3\2\2\2"+ + "\u02a9\u02b0\3\2\2\2\u02aa\u02b0\5~@\2\u02ab\u02ac\7\36\2\2\u02ac\u02ad"+ + "\5x=\2\u02ad\u02ae\7\37\2\2\u02ae\u02b0\3\2\2\2\u02af\u02a6\3\2\2\2\u02af"+ + "\u02aa\3\2\2\2\u02af\u02ab\3\2\2\2\u02b0y\3\2\2\2\u02b1\u02b2\7\"\2\2"+ + "\u02b2\u02b4\5f\64\2\u02b3\u02b5\7%\2\2\u02b4\u02b3\3\2\2\2\u02b4\u02b5"+ + "\3\2\2\2\u02b5\u02b6\3\2\2\2\u02b6\u02b7\7#\2\2\u02b7{\3\2\2\2\u02b8\u02bb"+ + "\5\u00acW\2\u02b9\u02bb\7\35\2\2\u02ba\u02b8\3\2\2\2\u02ba\u02b9\3\2\2"+ + "\2\u02bb}\3\2\2\2\u02bc\u02c5\5\u0080A\2\u02bd\u02c5\5\u00bc_\2\u02be"+ + "\u02c5\5\u0086D\2\u02bf\u02c5\5\u0092J\2\u02c0\u02c5\5\u0088E\2\u02c1"+ + "\u02c5\5\u008aF\2\u02c2\u02c5\5\u008cG\2\u02c3\u02c5\5\u008eH\2\u02c4"+ + "\u02bc\3\2\2\2\u02c4\u02bd\3\2\2\2\u02c4\u02be\3\2\2\2\u02c4\u02bf\3\2"+ + "\2\2\u02c4\u02c0\3\2\2\2\u02c4\u02c1\3\2\2\2\u02c4\u02c2\3\2\2\2\u02c4"+ + "\u02c3\3\2\2\2\u02c5\177\3\2\2\2\u02c6\u02c7\7\"\2\2\u02c7\u02c8\5\u0082"+ + "B\2\u02c8\u02c9\7#\2\2\u02c9\u02ca\5\u0084C\2\u02ca\u0081\3\2\2\2\u02cb"+ + "\u02cc\5\u009cO\2\u02cc\u0083\3\2\2\2\u02cd\u02ce\5x=\2\u02ce\u0085\3"+ + "\2\2\2\u02cf\u02d0\7@\2\2\u02d0\u02d1\5x=\2\u02d1\u0087\3\2\2\2\u02d2"+ + "\u02d3\7\6\2\2\u02d3\u02dc\7 \2\2\u02d4\u02d7\5\u0090I\2\u02d5\u02d7\5"+ + "$\23\2\u02d6\u02d4\3\2\2\2\u02d6\u02d5\3\2\2\2\u02d7\u02d8\3\2\2\2\u02d8"+ + "\u02d9\5\u00d0i\2\u02d9\u02db\3\2\2\2\u02da\u02d6\3\2\2\2\u02db\u02de"+ + "\3\2\2\2\u02dc\u02da\3\2\2\2\u02dc\u02dd\3\2\2\2\u02dd\u02df\3\2\2\2\u02de"+ + "\u02dc\3\2\2\2\u02df\u02e0\7!\2\2\u02e0\u0089\3\2\2\2\u02e1\u02e2\7\""+ + "\2\2\u02e2\u02e3\7#\2\2\u02e3\u02e4\5\u0084C\2\u02e4\u008b\3\2\2\2\u02e5"+ + "\u02e6\7\13\2\2\u02e6\u02e7\7\"\2\2\u02e7\u02e8\5x=\2\u02e8\u02e9\7#\2"+ + "\2\u02e9\u02ea\5\u0084C\2\u02ea\u008d\3\2\2\2\u02eb\u02f1\7\r\2\2\u02ec"+ + "\u02ed\7\r\2\2\u02ed\u02f1\7B\2\2\u02ee\u02ef\7B\2\2\u02ef\u02f1\7\r\2"+ + "\2\u02f0\u02eb\3\2\2\2\u02f0\u02ec\3\2\2\2\u02f0\u02ee\3\2\2\2\u02f1\u02f2"+ + "\3\2\2\2\u02f2\u02f3\5\u0084C\2\u02f3\u008f\3\2\2\2\u02f4\u02f5\7\35\2"+ + "\2\u02f5\u02f6\5\u0098M\2\u02f6\u02f7\5\u0096L\2\u02f7\u02fb\3\2\2\2\u02f8"+ + "\u02f9\7\35\2\2\u02f9\u02fb\5\u0098M\2\u02fa\u02f4\3\2\2\2\u02fa\u02f8"+ + "\3\2\2\2\u02fb\u0091\3\2\2\2\u02fc\u02fd\7\5\2\2\u02fd\u02fe\5\u0094K"+ + "\2\u02fe\u0093\3\2\2\2\u02ff\u0301\5\u0098M\2\u0300\u0302\5\u0096L\2\u0301"+ + "\u0300\3\2\2\2\u0301\u0302\3\2\2\2\u0302\u0095\3\2\2\2\u0303\u0306\5\u0098"+ + "M\2\u0304\u0306\5x=\2\u0305\u0303\3\2\2\2\u0305\u0304\3\2\2\2\u0306\u0097"+ + "\3\2\2\2\u0307\u0313\7\36\2\2\u0308\u030d\5\u009aN\2\u0309\u030a\7%\2"+ + "\2\u030a\u030c\5\u009aN\2\u030b\u0309\3\2\2\2\u030c\u030f\3\2\2\2\u030d"+ + "\u030b\3\2\2\2\u030d\u030e\3\2\2\2\u030e\u0311\3\2\2\2\u030f\u030d\3\2"+ + "\2\2\u0310\u0312\7%\2\2\u0311\u0310\3\2\2\2\u0311\u0312\3\2\2\2\u0312"+ + "\u0314\3\2\2\2\u0313\u0308\3\2\2\2\u0313\u0314\3\2\2\2\u0314\u0315\3\2"+ + "\2\2\u0315\u0316\7\37\2\2\u0316\u0099\3\2\2\2\u0317\u0319\5\22\n\2\u0318"+ + "\u0317\3\2\2\2\u0318\u0319\3\2\2\2\u0319\u031b\3\2\2\2\u031a\u031c\7,"+ + "\2\2\u031b\u031a\3\2\2\2\u031b\u031c\3\2\2\2\u031c\u031d\3\2\2\2\u031d"+ + "\u031e\5x=\2\u031e\u009b\3\2\2\2\u031f\u0320\bO\1\2\u0320\u0324\5\u009e"+ + "P\2\u0321\u0322\t\6\2\2\u0322\u0324\5\u009cO\b\u0323\u031f\3\2\2\2\u0323"+ + "\u0321\3\2\2\2\u0324\u0336\3\2\2\2\u0325\u0326\f\7\2\2\u0326\u0327\t\7"+ + "\2\2\u0327\u0335\5\u009cO\b\u0328\u0329\f\6\2\2\u0329\u032a\t\b\2\2\u032a"+ + "\u0335\5\u009cO\7\u032b\u032c\f\5\2\2\u032c\u032d\t\t\2\2\u032d\u0335"+ + "\5\u009cO\6\u032e\u032f\f\4\2\2\u032f\u0330\7.\2\2\u0330\u0335\5\u009c"+ + "O\5\u0331\u0332\f\3\2\2\u0332\u0333\7-\2\2\u0333\u0335\5\u009cO\4\u0334"+ + "\u0325\3\2\2\2\u0334\u0328\3\2\2\2\u0334\u032b\3\2\2\2\u0334\u032e\3\2"+ + "\2\2\u0334\u0331\3\2\2\2\u0335\u0338\3\2\2\2\u0336\u0334\3\2\2\2\u0336"+ + "\u0337\3\2\2\2\u0337\u009d\3\2\2\2\u0338\u0336\3\2\2\2\u0339\u033a\bP"+ + "\1\2\u033a\u033e\5\u00a2R\2\u033b\u033e\5\u00a0Q\2\u033c\u033e\5\u00ce"+ + "h\2\u033d\u0339\3\2\2\2\u033d\u033b\3\2\2\2\u033d\u033c\3\2\2\2\u033e"+ + "\u034a\3\2\2\2\u033f\u0346\f\3\2\2\u0340\u0341\7(\2\2\u0341\u0347\7\35"+ + "\2\2\u0342\u0347\5\u00c6d\2\u0343\u0347\5\u00c8e\2\u0344\u0347\5\u00ca"+ + "f\2\u0345\u0347\5\u00ccg\2\u0346\u0340\3\2\2\2\u0346\u0342\3\2\2\2\u0346"+ + "\u0343\3\2\2\2\u0346\u0344\3\2\2\2\u0346\u0345\3\2\2\2\u0347\u0349\3\2"+ + "\2\2\u0348\u033f\3\2\2\2\u0349\u034c\3\2\2\2\u034a\u0348\3\2\2\2\u034a"+ + "\u034b\3\2\2\2\u034b\u009f\3\2\2\2\u034c\u034a\3\2\2\2\u034d\u034e\5x"+ + "=\2\u034e\u034f\7\36\2\2\u034f\u0351\5\u009cO\2\u0350\u0352\7%\2\2\u0351"+ + "\u0350\3\2\2\2\u0351\u0352\3\2\2\2\u0352\u0353\3\2\2\2\u0353\u0354\7\37"+ + "\2\2\u0354\u00a1\3\2\2\2\u0355\u035f\5\u00a4S\2\u0356\u0358\5\u00aaV\2"+ + "\u0357\u0359\5z>\2\u0358\u0357\3\2\2\2\u0358\u0359\3\2\2\2\u0359\u035f"+ + "\3\2\2\2\u035a\u035b\7\36\2\2\u035b\u035c\5\u009cO\2\u035c\u035d\7\37"+ + "\2\2\u035d\u035f\3\2\2\2\u035e\u0355\3\2\2\2\u035e\u0356\3\2\2\2\u035e"+ + "\u035a\3\2\2\2\u035f\u00a3\3\2\2\2\u0360\u0364\5\u00a6T\2\u0361\u0364"+ + "\5\u00aeX\2\u0362\u0364\5\u00c4c\2\u0363\u0360\3\2\2\2\u0363\u0361\3\2"+ + "\2\2\u0363\u0362\3\2\2\2\u0364\u00a5\3\2\2\2\u0365\u036a\7\34\2\2\u0366"+ + "\u036a\5\u00a8U\2\u0367\u036a\5\u00c0a\2\u0368\u036a\7G\2\2\u0369\u0365"+ + "\3\2\2\2\u0369\u0366\3\2\2\2\u0369\u0367\3\2\2\2\u0369\u0368\3\2\2\2\u036a"+ + "\u00a7\3\2\2\2\u036b\u036c\t\n\2\2\u036c\u00a9\3\2\2\2\u036d\u036e\7\35"+ + "\2\2\u036e\u00ab\3\2\2\2\u036f\u0370\7\35\2\2\u0370\u0371\7(\2\2\u0371"+ + "\u0372\7\35\2\2\u0372\u00ad\3\2\2\2\u0373\u0374\5\u00b0Y\2\u0374\u0375"+ + "\5\u00b2Z\2\u0375\u00af\3\2\2\2\u0376\u0383\5\u00bc_\2\u0377\u0383\5\u0080"+ + "A\2\u0378\u0379\7\"\2\2\u0379\u037a\7,\2\2\u037a\u037b\7#\2\2\u037b\u0383"+ + "\5\u0084C\2\u037c\u0383\5\u008aF\2\u037d\u0383\5\u008cG\2\u037e\u0380"+ + "\5|?\2\u037f\u0381\5z>\2\u0380\u037f\3\2\2\2\u0380\u0381\3\2\2\2\u0381"+ + "\u0383\3\2\2\2\u0382\u0376\3\2\2\2\u0382\u0377\3\2\2\2\u0382\u0378\3\2"+ + "\2\2\u0382\u037c\3\2\2\2\u0382\u037d\3\2\2\2\u0382\u037e\3\2\2\2\u0383"+ + "\u00b1\3\2\2\2\u0384\u0389\7 \2\2\u0385\u0387\5\u00b4[\2\u0386\u0388\7"+ + "%\2\2\u0387\u0386\3\2\2\2\u0387\u0388\3\2\2\2\u0388\u038a\3\2\2\2\u0389"+ + "\u0385\3\2\2\2\u0389\u038a\3\2\2\2\u038a\u038b\3\2\2\2\u038b\u038c\7!"+ + "\2\2\u038c\u00b3\3\2\2\2\u038d\u0392\5\u00b6\\\2\u038e\u038f\7%\2\2\u038f"+ + "\u0391\5\u00b6\\\2\u0390\u038e\3\2\2\2\u0391\u0394\3\2\2\2\u0392\u0390"+ + "\3\2\2\2\u0392\u0393\3\2\2\2\u0393\u00b5\3\2\2\2\u0394\u0392\3\2\2\2\u0395"+ + "\u0396\5\u00b8]\2\u0396\u0397\7\'\2\2\u0397\u0399\3\2\2\2\u0398\u0395"+ + "\3\2\2\2\u0398\u0399\3\2\2\2\u0399\u039a\3\2\2\2\u039a\u039b\5\u00ba^"+ + "\2\u039b\u00b7\3\2\2\2\u039c\u039f\5\u009cO\2\u039d\u039f\5\u00b2Z\2\u039e"+ + "\u039c\3\2\2\2\u039e\u039d\3\2\2\2\u039f\u00b9\3\2\2\2\u03a0\u03a3\5\u009c"+ + "O\2\u03a1\u03a3\5\u00b2Z\2\u03a2\u03a0\3\2\2\2\u03a2\u03a1\3\2\2\2\u03a3"+ + "\u00bb\3\2\2\2\u03a4\u03a5\7\f\2\2\u03a5\u03ab\7 \2\2\u03a6\u03a7\5\u00be"+ + "`\2\u03a7\u03a8\5\u00d0i\2\u03a8\u03aa\3\2\2\2\u03a9\u03a6\3\2\2\2\u03aa"+ + "\u03ad\3\2\2\2\u03ab\u03a9\3\2\2\2\u03ab\u03ac\3\2\2\2\u03ac\u03ae\3\2"+ + "\2\2\u03ad\u03ab\3\2\2\2\u03ae\u03af\7!\2\2\u03af\u00bd\3\2\2\2\u03b0"+ + "\u03b1\5\22\n\2\u03b1\u03b2\5x=\2\u03b2\u03b5\3\2\2\2\u03b3\u03b5\5\u00c2"+ + "b\2\u03b4\u03b0\3\2\2\2\u03b4\u03b3\3\2\2\2\u03b5\u03b7\3\2\2\2\u03b6"+ + "\u03b8\5\u00c0a\2\u03b7\u03b6\3\2\2\2\u03b7\u03b8\3\2\2\2\u03b8\u00bf"+ + "\3\2\2\2\u03b9\u03ba\t\13\2\2\u03ba\u00c1\3\2\2\2\u03bb\u03bd\7@\2\2\u03bc"+ + "\u03bb\3\2\2\2\u03bc\u03bd\3\2\2\2\u03bd\u03be\3\2\2\2\u03be\u03c0\5|"+ + "?\2\u03bf\u03c1\5z>\2\u03c0\u03bf\3\2\2\2\u03c0\u03c1\3\2\2\2\u03c1\u00c3"+ + "\3\2\2\2\u03c2\u03c3\7\5\2\2\u03c3\u03c4\5\u0094K\2\u03c4\u03c5\5\62\32"+ + "\2\u03c5\u00c5\3\2\2\2\u03c6\u03c7\7\"\2\2\u03c7\u03c8\5\u009cO\2\u03c8"+ + "\u03c9\7#\2\2\u03c9\u00c7\3\2\2\2\u03ca\u03da\7\"\2\2\u03cb\u03cd\5\u009c"+ + "O\2\u03cc\u03cb\3\2\2\2\u03cc\u03cd\3\2\2\2\u03cd\u03ce\3\2\2\2\u03ce"+ + "\u03d0\7\'\2\2\u03cf\u03d1\5\u009cO\2\u03d0\u03cf\3\2\2\2\u03d0\u03d1"+ + "\3\2\2\2\u03d1\u03db\3\2\2\2\u03d2\u03d4\5\u009cO\2\u03d3\u03d2\3\2\2"+ + "\2\u03d3\u03d4\3\2\2\2\u03d4\u03d5\3\2\2\2\u03d5\u03d6\7\'\2\2\u03d6\u03d7"+ + "\5\u009cO\2\u03d7\u03d8\7\'\2\2\u03d8\u03d9\5\u009cO\2\u03d9\u03db\3\2"+ + "\2\2\u03da\u03cc\3\2\2\2\u03da\u03d3\3\2\2\2\u03db\u03dc\3\2\2\2\u03dc"+ + "\u03dd\7#\2\2\u03dd\u00c9\3\2\2\2\u03de\u03df\7(\2\2\u03df\u03e0\7\36"+ + "\2\2\u03e0\u03e1\5x=\2\u03e1\u03e2\7\37\2\2\u03e2\u00cb\3\2\2\2\u03e3"+ + "\u03f2\7\36\2\2\u03e4\u03eb\5\24\13\2\u03e5\u03e8\5x=\2\u03e6\u03e7\7"+ + "%\2\2\u03e7\u03e9\5\24\13\2\u03e8\u03e6\3\2\2\2\u03e8\u03e9\3\2\2\2\u03e9"+ + "\u03eb\3\2\2\2\u03ea\u03e4\3\2\2\2\u03ea\u03e5\3\2\2\2\u03eb\u03ed\3\2"+ + "\2\2\u03ec\u03ee\7,\2\2\u03ed\u03ec\3\2\2\2\u03ed\u03ee\3\2\2\2\u03ee"+ + "\u03f0\3\2\2\2\u03ef\u03f1\7%\2\2\u03f0\u03ef\3\2\2\2\u03f0\u03f1\3\2"+ + "\2\2\u03f1\u03f3\3\2\2\2\u03f2\u03ea\3\2\2\2\u03f2\u03f3\3\2\2\2\u03f3"+ + "\u03f4\3\2\2\2\u03f4\u03f5\7\37\2\2\u03f5\u00cd\3\2\2\2\u03f6\u03f7\5"+ + "x=\2\u03f7\u03f8\7(\2\2\u03f8\u03f9\7\35\2\2\u03f9\u00cf\3\2\2\2\u03fa"+ + "\u03ff\7&\2\2\u03fb\u03ff\7\2\2\3\u03fc\u03ff\7[\2\2\u03fd\u03ff\6i\t"+ + "\2\u03fe\u03fa\3\2\2\2\u03fe\u03fb\3\2\2\2\u03fe\u03fc\3\2\2\2\u03fe\u03fd"+ + "\3\2\2\2\u03ff\u00d1\3\2\2\2{\u00d9\u00df\u00e5\u00f5\u00f9\u00fc\u0105"+ + "\u010f\u0113\u0117\u011b\u0122\u012a\u0132\u013d\u0141\u0145\u014d\u0157"+ + "\u0164\u0168\u016f\u0173\u017a\u0186\u018a\u0190\u0194\u0198\u019d\u01a0"+ + "\u01a3\u01aa\u01bb\u01c2\u01d2\u01dd\u01e1\u01e5\u01e9\u01fc\u0202\u0204"+ + "\u0208\u020c\u020f\u0213\u0215\u021b\u0223\u0228\u0233\u0239\u0240\u024b"+ + "\u0250\u0254\u0259\u025d\u0265\u026d\u0272\u0275\u027d\u0283\u0287\u0289"+ + "\u028e\u0292\u0296\u029e\u02a8\u02af\u02b4\u02ba\u02c4\u02d6\u02dc\u02f0"+ + "\u02fa\u0301\u0305\u030d\u0311\u0313\u0318\u031b\u0323\u0334\u0336\u033d"+ + "\u0346\u034a\u0351\u0358\u035e\u0363\u0369\u0380\u0382\u0387\u0389\u0392"+ + "\u0398\u039e\u03a2\u03ab\u03b4\u03b7\u03bc\u03c0\u03cc\u03d0\u03d3\u03da"+ + "\u03e8\u03ea\u03ed\u03f0\u03f2\u03fe"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.tokens b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.tokens new file mode 100644 index 000000000..3d04e655a --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParser.tokens @@ -0,0 +1,153 @@ +BREAK=1 +DEFAULT=2 +FUNC=3 +INTERFACE=4 +SELECT=5 +CASE=6 +DEFER=7 +GO=8 +MAP=9 +STRUCT=10 +CHAN=11 +ELSE=12 +GOTO=13 +PACKAGE=14 +SWITCH=15 +CONST=16 +FALLTHROUGH=17 +IF=18 +RANGE=19 +TYPE=20 +CONTINUE=21 +FOR=22 +IMPORT=23 +RETURN=24 +VAR=25 +NIL_LIT=26 +IDENTIFIER=27 +L_PAREN=28 +R_PAREN=29 +L_CURLY=30 +R_CURLY=31 +L_BRACKET=32 +R_BRACKET=33 +ASSIGN=34 +COMMA=35 +SEMI=36 +COLON=37 +DOT=38 +PLUS_PLUS=39 +MINUS_MINUS=40 +DECLARE_ASSIGN=41 +ELLIPSIS=42 +LOGICAL_OR=43 +LOGICAL_AND=44 +EQUALS=45 +NOT_EQUALS=46 +LESS=47 +LESS_OR_EQUALS=48 +GREATER=49 +GREATER_OR_EQUALS=50 +OR=51 +DIV=52 +MOD=53 +LSHIFT=54 +RSHIFT=55 +BIT_CLEAR=56 +UNDERLYING=57 +EXCLAMATION=58 +PLUS=59 +MINUS=60 +CARET=61 +STAR=62 +AMPERSAND=63 +RECEIVE=64 +DECIMAL_LIT=65 +BINARY_LIT=66 +OCTAL_LIT=67 +HEX_LIT=68 +FLOAT_LIT=69 +DECIMAL_FLOAT_LIT=70 +HEX_FLOAT_LIT=71 +IMAGINARY_LIT=72 +RUNE_LIT=73 +BYTE_VALUE=74 +OCTAL_BYTE_VALUE=75 +HEX_BYTE_VALUE=76 +LITTLE_U_VALUE=77 +BIG_U_VALUE=78 +RAW_STRING_LIT=79 +INTERPRETED_STRING_LIT=80 +WS=81 +COMMENT=82 +TERMINATOR=83 +LINE_COMMENT=84 +NEWLINE=85 +WS_NLSEMI=86 +COMMENT_NLSEMI=87 +LINE_COMMENT_NLSEMI=88 +EOS=89 +OTHER=90 +'break'=1 +'default'=2 +'func'=3 +'interface'=4 +'select'=5 +'case'=6 +'defer'=7 +'go'=8 +'map'=9 +'struct'=10 +'chan'=11 +'else'=12 +'goto'=13 +'package'=14 +'switch'=15 +'const'=16 +'fallthrough'=17 +'if'=18 +'range'=19 +'type'=20 +'continue'=21 +'for'=22 +'import'=23 +'return'=24 +'var'=25 +'nil'=26 +'('=28 +')'=29 +'{'=30 +'}'=31 +'['=32 +']'=33 +'='=34 +','=35 +';'=36 +':'=37 +'.'=38 +'++'=39 +'--'=40 +':='=41 +'...'=42 +'||'=43 +'&&'=44 +'=='=45 +'!='=46 +'<'=47 +'<='=48 +'>'=49 +'>='=50 +'|'=51 +'/'=52 +'%'=53 +'<<'=54 +'>>'=55 +'&^'=56 +'~'=57 +'!'=58 +'+'=59 +'-'=60 +'^'=61 +'*'=62 +'&'=63 +'<-'=64 diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserBase.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserBase.java new file mode 100644 index 000000000..6aa5c5da0 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserBase.java @@ -0,0 +1,28 @@ +package run.mone.antlr.golang; + +import org.antlr.v4.runtime.BufferedTokenStream; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.TokenStream; + +/** + * @author goodjava@qq.com + * @date 2024/1/29 16:33 + */ +public abstract class GoParserBase extends Parser +{ + protected GoParserBase(TokenStream input) { + super(input); + } + + + /** + * Returns true if the current Token is a closing bracket (")" or "}") + */ + protected boolean closingBracket() + { + BufferedTokenStream stream = (BufferedTokenStream)_input; + int prevTokenType = stream.LA(1); + + return prevTokenType == GoParser.R_CURLY || prevTokenType == GoParser.R_PAREN; + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserBaseListener.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserBaseListener.java new file mode 100644 index 000000000..ac039b2dd --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserBaseListener.java @@ -0,0 +1,1286 @@ +package run.mone.antlr.golang;// Generated from GoParser.g4 by ANTLR 4.7.1 + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link GoParserListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +public class GoParserBaseListener implements GoParserListener { + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSourceFile(GoParser.SourceFileContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSourceFile(GoParser.SourceFileContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPackageClause(GoParser.PackageClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPackageClause(GoParser.PackageClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterImportDecl(GoParser.ImportDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitImportDecl(GoParser.ImportDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterImportSpec(GoParser.ImportSpecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitImportSpec(GoParser.ImportSpecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterImportPath(GoParser.ImportPathContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitImportPath(GoParser.ImportPathContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterDeclaration(GoParser.DeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitDeclaration(GoParser.DeclarationContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterConstDecl(GoParser.ConstDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitConstDecl(GoParser.ConstDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterConstSpec(GoParser.ConstSpecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitConstSpec(GoParser.ConstSpecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterIdentifierList(GoParser.IdentifierListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitIdentifierList(GoParser.IdentifierListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExpressionList(GoParser.ExpressionListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExpressionList(GoParser.ExpressionListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterComment(GoParser.CommentContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitComment(GoParser.CommentContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeDecl(GoParser.TypeDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeDecl(GoParser.TypeDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeSpec(GoParser.TypeSpecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeSpec(GoParser.TypeSpecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterAliasDecl(GoParser.AliasDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitAliasDecl(GoParser.AliasDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeDef(GoParser.TypeDefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeDef(GoParser.TypeDefContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeParameters(GoParser.TypeParametersContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeParameters(GoParser.TypeParametersContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeParameterDecl(GoParser.TypeParameterDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeParameterDecl(GoParser.TypeParameterDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeElement(GoParser.TypeElementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeElement(GoParser.TypeElementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeTerm(GoParser.TypeTermContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeTerm(GoParser.TypeTermContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFunctionDecl(GoParser.FunctionDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFunctionDecl(GoParser.FunctionDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterMethodDecl(GoParser.MethodDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitMethodDecl(GoParser.MethodDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterReceiver(GoParser.ReceiverContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitReceiver(GoParser.ReceiverContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterVarDecl(GoParser.VarDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitVarDecl(GoParser.VarDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterVarSpec(GoParser.VarSpecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitVarSpec(GoParser.VarSpecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterBlock(GoParser.BlockContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitBlock(GoParser.BlockContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterStatementList(GoParser.StatementListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitStatementList(GoParser.StatementListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterStatement(GoParser.StatementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitStatement(GoParser.StatementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSimpleStmt(GoParser.SimpleStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSimpleStmt(GoParser.SimpleStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExpressionStmt(GoParser.ExpressionStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExpressionStmt(GoParser.ExpressionStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSendStmt(GoParser.SendStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSendStmt(GoParser.SendStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterIncDecStmt(GoParser.IncDecStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitIncDecStmt(GoParser.IncDecStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterAssignment(GoParser.AssignmentContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitAssignment(GoParser.AssignmentContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterAssign_op(GoParser.Assign_opContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitAssign_op(GoParser.Assign_opContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterShortVarDecl(GoParser.ShortVarDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitShortVarDecl(GoParser.ShortVarDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterLabeledStmt(GoParser.LabeledStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitLabeledStmt(GoParser.LabeledStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterReturnStmt(GoParser.ReturnStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitReturnStmt(GoParser.ReturnStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterBreakStmt(GoParser.BreakStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitBreakStmt(GoParser.BreakStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterContinueStmt(GoParser.ContinueStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitContinueStmt(GoParser.ContinueStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterGotoStmt(GoParser.GotoStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitGotoStmt(GoParser.GotoStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFallthroughStmt(GoParser.FallthroughStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFallthroughStmt(GoParser.FallthroughStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterDeferStmt(GoParser.DeferStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitDeferStmt(GoParser.DeferStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterIfStmt(GoParser.IfStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitIfStmt(GoParser.IfStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSwitchStmt(GoParser.SwitchStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSwitchStmt(GoParser.SwitchStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprSwitchStmt(GoParser.ExprSwitchStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprSwitchStmt(GoParser.ExprSwitchStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprCaseClause(GoParser.ExprCaseClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprCaseClause(GoParser.ExprCaseClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExprSwitchCase(GoParser.ExprSwitchCaseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExprSwitchCase(GoParser.ExprSwitchCaseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeSwitchStmt(GoParser.TypeSwitchStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeSwitchStmt(GoParser.TypeSwitchStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeSwitchGuard(GoParser.TypeSwitchGuardContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeSwitchGuard(GoParser.TypeSwitchGuardContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeCaseClause(GoParser.TypeCaseClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeCaseClause(GoParser.TypeCaseClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeSwitchCase(GoParser.TypeSwitchCaseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeSwitchCase(GoParser.TypeSwitchCaseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeList(GoParser.TypeListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeList(GoParser.TypeListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSelectStmt(GoParser.SelectStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSelectStmt(GoParser.SelectStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterCommClause(GoParser.CommClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitCommClause(GoParser.CommClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterCommCase(GoParser.CommCaseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitCommCase(GoParser.CommCaseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterRecvStmt(GoParser.RecvStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitRecvStmt(GoParser.RecvStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterForStmt(GoParser.ForStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitForStmt(GoParser.ForStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterForClause(GoParser.ForClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitForClause(GoParser.ForClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterRangeClause(GoParser.RangeClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitRangeClause(GoParser.RangeClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterGoStmt(GoParser.GoStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitGoStmt(GoParser.GoStmtContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterType_(GoParser.Type_Context ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitType_(GoParser.Type_Context ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeArgs(GoParser.TypeArgsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeArgs(GoParser.TypeArgsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeName(GoParser.TypeNameContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeName(GoParser.TypeNameContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeLit(GoParser.TypeLitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeLit(GoParser.TypeLitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterArrayType(GoParser.ArrayTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitArrayType(GoParser.ArrayTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterArrayLength(GoParser.ArrayLengthContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitArrayLength(GoParser.ArrayLengthContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterElementType(GoParser.ElementTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitElementType(GoParser.ElementTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPointerType(GoParser.PointerTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPointerType(GoParser.PointerTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInterfaceType(GoParser.InterfaceTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInterfaceType(GoParser.InterfaceTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSliceType(GoParser.SliceTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSliceType(GoParser.SliceTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterMapType(GoParser.MapTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitMapType(GoParser.MapTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterChannelType(GoParser.ChannelTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitChannelType(GoParser.ChannelTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterMethodSpec(GoParser.MethodSpecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitMethodSpec(GoParser.MethodSpecContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFunctionType(GoParser.FunctionTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFunctionType(GoParser.FunctionTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSignature(GoParser.SignatureContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSignature(GoParser.SignatureContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterResult(GoParser.ResultContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitResult(GoParser.ResultContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterParameters(GoParser.ParametersContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitParameters(GoParser.ParametersContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterParameterDecl(GoParser.ParameterDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitParameterDecl(GoParser.ParameterDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterExpression(GoParser.ExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitExpression(GoParser.ExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterPrimaryExpr(GoParser.PrimaryExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitPrimaryExpr(GoParser.PrimaryExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterConversion(GoParser.ConversionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitConversion(GoParser.ConversionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterOperand(GoParser.OperandContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitOperand(GoParser.OperandContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterLiteral(GoParser.LiteralContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitLiteral(GoParser.LiteralContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterBasicLit(GoParser.BasicLitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitBasicLit(GoParser.BasicLitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterInteger(GoParser.IntegerContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitInteger(GoParser.IntegerContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterOperandName(GoParser.OperandNameContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitOperandName(GoParser.OperandNameContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterQualifiedIdent(GoParser.QualifiedIdentContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitQualifiedIdent(GoParser.QualifiedIdentContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterCompositeLit(GoParser.CompositeLitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitCompositeLit(GoParser.CompositeLitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterLiteralType(GoParser.LiteralTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitLiteralType(GoParser.LiteralTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterLiteralValue(GoParser.LiteralValueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitLiteralValue(GoParser.LiteralValueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterElementList(GoParser.ElementListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitElementList(GoParser.ElementListContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterKeyedElement(GoParser.KeyedElementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitKeyedElement(GoParser.KeyedElementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterKey(GoParser.KeyContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitKey(GoParser.KeyContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterElement(GoParser.ElementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitElement(GoParser.ElementContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterStructType(GoParser.StructTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitStructType(GoParser.StructTypeContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFieldDecl(GoParser.FieldDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFieldDecl(GoParser.FieldDeclContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterString_(GoParser.String_Context ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitString_(GoParser.String_Context ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEmbeddedField(GoParser.EmbeddedFieldContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEmbeddedField(GoParser.EmbeddedFieldContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterFunctionLit(GoParser.FunctionLitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitFunctionLit(GoParser.FunctionLitContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterIndex(GoParser.IndexContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitIndex(GoParser.IndexContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterSlice_(GoParser.Slice_Context ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitSlice_(GoParser.Slice_Context ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterTypeAssertion(GoParser.TypeAssertionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitTypeAssertion(GoParser.TypeAssertionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterArguments(GoParser.ArgumentsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitArguments(GoParser.ArgumentsContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterMethodExpr(GoParser.MethodExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitMethodExpr(GoParser.MethodExprContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEos(GoParser.EosContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEos(GoParser.EosContext ctx) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitErrorNode(ErrorNode node) { } +} \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserListener.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserListener.java new file mode 100644 index 000000000..63a6b2b43 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/GoParserListener.java @@ -0,0 +1,1049 @@ +package run.mone.antlr.golang;// Generated from GoParser.g4 by ANTLR 4.7.1 +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link GoParser}. + */ +public interface GoParserListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link GoParser#sourceFile}. + * @param ctx the parse tree + */ + void enterSourceFile(GoParser.SourceFileContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#sourceFile}. + * @param ctx the parse tree + */ + void exitSourceFile(GoParser.SourceFileContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#packageClause}. + * @param ctx the parse tree + */ + void enterPackageClause(GoParser.PackageClauseContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#packageClause}. + * @param ctx the parse tree + */ + void exitPackageClause(GoParser.PackageClauseContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#importDecl}. + * @param ctx the parse tree + */ + void enterImportDecl(GoParser.ImportDeclContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#importDecl}. + * @param ctx the parse tree + */ + void exitImportDecl(GoParser.ImportDeclContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#importSpec}. + * @param ctx the parse tree + */ + void enterImportSpec(GoParser.ImportSpecContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#importSpec}. + * @param ctx the parse tree + */ + void exitImportSpec(GoParser.ImportSpecContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#importPath}. + * @param ctx the parse tree + */ + void enterImportPath(GoParser.ImportPathContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#importPath}. + * @param ctx the parse tree + */ + void exitImportPath(GoParser.ImportPathContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#declaration}. + * @param ctx the parse tree + */ + void enterDeclaration(GoParser.DeclarationContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#declaration}. + * @param ctx the parse tree + */ + void exitDeclaration(GoParser.DeclarationContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#constDecl}. + * @param ctx the parse tree + */ + void enterConstDecl(GoParser.ConstDeclContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#constDecl}. + * @param ctx the parse tree + */ + void exitConstDecl(GoParser.ConstDeclContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#constSpec}. + * @param ctx the parse tree + */ + void enterConstSpec(GoParser.ConstSpecContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#constSpec}. + * @param ctx the parse tree + */ + void exitConstSpec(GoParser.ConstSpecContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#identifierList}. + * @param ctx the parse tree + */ + void enterIdentifierList(GoParser.IdentifierListContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#identifierList}. + * @param ctx the parse tree + */ + void exitIdentifierList(GoParser.IdentifierListContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#expressionList}. + * @param ctx the parse tree + */ + void enterExpressionList(GoParser.ExpressionListContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#expressionList}. + * @param ctx the parse tree + */ + void exitExpressionList(GoParser.ExpressionListContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#comment}. + * @param ctx the parse tree + */ + void enterComment(GoParser.CommentContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#comment}. + * @param ctx the parse tree + */ + void exitComment(GoParser.CommentContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeDecl}. + * @param ctx the parse tree + */ + void enterTypeDecl(GoParser.TypeDeclContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeDecl}. + * @param ctx the parse tree + */ + void exitTypeDecl(GoParser.TypeDeclContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeSpec}. + * @param ctx the parse tree + */ + void enterTypeSpec(GoParser.TypeSpecContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeSpec}. + * @param ctx the parse tree + */ + void exitTypeSpec(GoParser.TypeSpecContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#aliasDecl}. + * @param ctx the parse tree + */ + void enterAliasDecl(GoParser.AliasDeclContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#aliasDecl}. + * @param ctx the parse tree + */ + void exitAliasDecl(GoParser.AliasDeclContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeDef}. + * @param ctx the parse tree + */ + void enterTypeDef(GoParser.TypeDefContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeDef}. + * @param ctx the parse tree + */ + void exitTypeDef(GoParser.TypeDefContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeParameters}. + * @param ctx the parse tree + */ + void enterTypeParameters(GoParser.TypeParametersContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeParameters}. + * @param ctx the parse tree + */ + void exitTypeParameters(GoParser.TypeParametersContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeParameterDecl}. + * @param ctx the parse tree + */ + void enterTypeParameterDecl(GoParser.TypeParameterDeclContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeParameterDecl}. + * @param ctx the parse tree + */ + void exitTypeParameterDecl(GoParser.TypeParameterDeclContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeElement}. + * @param ctx the parse tree + */ + void enterTypeElement(GoParser.TypeElementContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeElement}. + * @param ctx the parse tree + */ + void exitTypeElement(GoParser.TypeElementContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeTerm}. + * @param ctx the parse tree + */ + void enterTypeTerm(GoParser.TypeTermContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeTerm}. + * @param ctx the parse tree + */ + void exitTypeTerm(GoParser.TypeTermContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#functionDecl}. + * @param ctx the parse tree + */ + void enterFunctionDecl(GoParser.FunctionDeclContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#functionDecl}. + * @param ctx the parse tree + */ + void exitFunctionDecl(GoParser.FunctionDeclContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#methodDecl}. + * @param ctx the parse tree + */ + void enterMethodDecl(GoParser.MethodDeclContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#methodDecl}. + * @param ctx the parse tree + */ + void exitMethodDecl(GoParser.MethodDeclContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#receiver}. + * @param ctx the parse tree + */ + void enterReceiver(GoParser.ReceiverContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#receiver}. + * @param ctx the parse tree + */ + void exitReceiver(GoParser.ReceiverContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#varDecl}. + * @param ctx the parse tree + */ + void enterVarDecl(GoParser.VarDeclContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#varDecl}. + * @param ctx the parse tree + */ + void exitVarDecl(GoParser.VarDeclContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#varSpec}. + * @param ctx the parse tree + */ + void enterVarSpec(GoParser.VarSpecContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#varSpec}. + * @param ctx the parse tree + */ + void exitVarSpec(GoParser.VarSpecContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#block}. + * @param ctx the parse tree + */ + void enterBlock(GoParser.BlockContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#block}. + * @param ctx the parse tree + */ + void exitBlock(GoParser.BlockContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#statementList}. + * @param ctx the parse tree + */ + void enterStatementList(GoParser.StatementListContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#statementList}. + * @param ctx the parse tree + */ + void exitStatementList(GoParser.StatementListContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#statement}. + * @param ctx the parse tree + */ + void enterStatement(GoParser.StatementContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#statement}. + * @param ctx the parse tree + */ + void exitStatement(GoParser.StatementContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#simpleStmt}. + * @param ctx the parse tree + */ + void enterSimpleStmt(GoParser.SimpleStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#simpleStmt}. + * @param ctx the parse tree + */ + void exitSimpleStmt(GoParser.SimpleStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#expressionStmt}. + * @param ctx the parse tree + */ + void enterExpressionStmt(GoParser.ExpressionStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#expressionStmt}. + * @param ctx the parse tree + */ + void exitExpressionStmt(GoParser.ExpressionStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#sendStmt}. + * @param ctx the parse tree + */ + void enterSendStmt(GoParser.SendStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#sendStmt}. + * @param ctx the parse tree + */ + void exitSendStmt(GoParser.SendStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#incDecStmt}. + * @param ctx the parse tree + */ + void enterIncDecStmt(GoParser.IncDecStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#incDecStmt}. + * @param ctx the parse tree + */ + void exitIncDecStmt(GoParser.IncDecStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#assignment}. + * @param ctx the parse tree + */ + void enterAssignment(GoParser.AssignmentContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#assignment}. + * @param ctx the parse tree + */ + void exitAssignment(GoParser.AssignmentContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#assign_op}. + * @param ctx the parse tree + */ + void enterAssign_op(GoParser.Assign_opContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#assign_op}. + * @param ctx the parse tree + */ + void exitAssign_op(GoParser.Assign_opContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#shortVarDecl}. + * @param ctx the parse tree + */ + void enterShortVarDecl(GoParser.ShortVarDeclContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#shortVarDecl}. + * @param ctx the parse tree + */ + void exitShortVarDecl(GoParser.ShortVarDeclContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#labeledStmt}. + * @param ctx the parse tree + */ + void enterLabeledStmt(GoParser.LabeledStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#labeledStmt}. + * @param ctx the parse tree + */ + void exitLabeledStmt(GoParser.LabeledStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#returnStmt}. + * @param ctx the parse tree + */ + void enterReturnStmt(GoParser.ReturnStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#returnStmt}. + * @param ctx the parse tree + */ + void exitReturnStmt(GoParser.ReturnStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#breakStmt}. + * @param ctx the parse tree + */ + void enterBreakStmt(GoParser.BreakStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#breakStmt}. + * @param ctx the parse tree + */ + void exitBreakStmt(GoParser.BreakStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#continueStmt}. + * @param ctx the parse tree + */ + void enterContinueStmt(GoParser.ContinueStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#continueStmt}. + * @param ctx the parse tree + */ + void exitContinueStmt(GoParser.ContinueStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#gotoStmt}. + * @param ctx the parse tree + */ + void enterGotoStmt(GoParser.GotoStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#gotoStmt}. + * @param ctx the parse tree + */ + void exitGotoStmt(GoParser.GotoStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#fallthroughStmt}. + * @param ctx the parse tree + */ + void enterFallthroughStmt(GoParser.FallthroughStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#fallthroughStmt}. + * @param ctx the parse tree + */ + void exitFallthroughStmt(GoParser.FallthroughStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#deferStmt}. + * @param ctx the parse tree + */ + void enterDeferStmt(GoParser.DeferStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#deferStmt}. + * @param ctx the parse tree + */ + void exitDeferStmt(GoParser.DeferStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#ifStmt}. + * @param ctx the parse tree + */ + void enterIfStmt(GoParser.IfStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#ifStmt}. + * @param ctx the parse tree + */ + void exitIfStmt(GoParser.IfStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#switchStmt}. + * @param ctx the parse tree + */ + void enterSwitchStmt(GoParser.SwitchStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#switchStmt}. + * @param ctx the parse tree + */ + void exitSwitchStmt(GoParser.SwitchStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#exprSwitchStmt}. + * @param ctx the parse tree + */ + void enterExprSwitchStmt(GoParser.ExprSwitchStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#exprSwitchStmt}. + * @param ctx the parse tree + */ + void exitExprSwitchStmt(GoParser.ExprSwitchStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#exprCaseClause}. + * @param ctx the parse tree + */ + void enterExprCaseClause(GoParser.ExprCaseClauseContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#exprCaseClause}. + * @param ctx the parse tree + */ + void exitExprCaseClause(GoParser.ExprCaseClauseContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#exprSwitchCase}. + * @param ctx the parse tree + */ + void enterExprSwitchCase(GoParser.ExprSwitchCaseContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#exprSwitchCase}. + * @param ctx the parse tree + */ + void exitExprSwitchCase(GoParser.ExprSwitchCaseContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeSwitchStmt}. + * @param ctx the parse tree + */ + void enterTypeSwitchStmt(GoParser.TypeSwitchStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeSwitchStmt}. + * @param ctx the parse tree + */ + void exitTypeSwitchStmt(GoParser.TypeSwitchStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeSwitchGuard}. + * @param ctx the parse tree + */ + void enterTypeSwitchGuard(GoParser.TypeSwitchGuardContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeSwitchGuard}. + * @param ctx the parse tree + */ + void exitTypeSwitchGuard(GoParser.TypeSwitchGuardContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeCaseClause}. + * @param ctx the parse tree + */ + void enterTypeCaseClause(GoParser.TypeCaseClauseContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeCaseClause}. + * @param ctx the parse tree + */ + void exitTypeCaseClause(GoParser.TypeCaseClauseContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeSwitchCase}. + * @param ctx the parse tree + */ + void enterTypeSwitchCase(GoParser.TypeSwitchCaseContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeSwitchCase}. + * @param ctx the parse tree + */ + void exitTypeSwitchCase(GoParser.TypeSwitchCaseContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeList}. + * @param ctx the parse tree + */ + void enterTypeList(GoParser.TypeListContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeList}. + * @param ctx the parse tree + */ + void exitTypeList(GoParser.TypeListContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#selectStmt}. + * @param ctx the parse tree + */ + void enterSelectStmt(GoParser.SelectStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#selectStmt}. + * @param ctx the parse tree + */ + void exitSelectStmt(GoParser.SelectStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#commClause}. + * @param ctx the parse tree + */ + void enterCommClause(GoParser.CommClauseContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#commClause}. + * @param ctx the parse tree + */ + void exitCommClause(GoParser.CommClauseContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#commCase}. + * @param ctx the parse tree + */ + void enterCommCase(GoParser.CommCaseContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#commCase}. + * @param ctx the parse tree + */ + void exitCommCase(GoParser.CommCaseContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#recvStmt}. + * @param ctx the parse tree + */ + void enterRecvStmt(GoParser.RecvStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#recvStmt}. + * @param ctx the parse tree + */ + void exitRecvStmt(GoParser.RecvStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#forStmt}. + * @param ctx the parse tree + */ + void enterForStmt(GoParser.ForStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#forStmt}. + * @param ctx the parse tree + */ + void exitForStmt(GoParser.ForStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#forClause}. + * @param ctx the parse tree + */ + void enterForClause(GoParser.ForClauseContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#forClause}. + * @param ctx the parse tree + */ + void exitForClause(GoParser.ForClauseContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#rangeClause}. + * @param ctx the parse tree + */ + void enterRangeClause(GoParser.RangeClauseContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#rangeClause}. + * @param ctx the parse tree + */ + void exitRangeClause(GoParser.RangeClauseContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#goStmt}. + * @param ctx the parse tree + */ + void enterGoStmt(GoParser.GoStmtContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#goStmt}. + * @param ctx the parse tree + */ + void exitGoStmt(GoParser.GoStmtContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#type_}. + * @param ctx the parse tree + */ + void enterType_(GoParser.Type_Context ctx); + /** + * Exit a parse tree produced by {@link GoParser#type_}. + * @param ctx the parse tree + */ + void exitType_(GoParser.Type_Context ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeArgs}. + * @param ctx the parse tree + */ + void enterTypeArgs(GoParser.TypeArgsContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeArgs}. + * @param ctx the parse tree + */ + void exitTypeArgs(GoParser.TypeArgsContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeName}. + * @param ctx the parse tree + */ + void enterTypeName(GoParser.TypeNameContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeName}. + * @param ctx the parse tree + */ + void exitTypeName(GoParser.TypeNameContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeLit}. + * @param ctx the parse tree + */ + void enterTypeLit(GoParser.TypeLitContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeLit}. + * @param ctx the parse tree + */ + void exitTypeLit(GoParser.TypeLitContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#arrayType}. + * @param ctx the parse tree + */ + void enterArrayType(GoParser.ArrayTypeContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#arrayType}. + * @param ctx the parse tree + */ + void exitArrayType(GoParser.ArrayTypeContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#arrayLength}. + * @param ctx the parse tree + */ + void enterArrayLength(GoParser.ArrayLengthContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#arrayLength}. + * @param ctx the parse tree + */ + void exitArrayLength(GoParser.ArrayLengthContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#elementType}. + * @param ctx the parse tree + */ + void enterElementType(GoParser.ElementTypeContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#elementType}. + * @param ctx the parse tree + */ + void exitElementType(GoParser.ElementTypeContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#pointerType}. + * @param ctx the parse tree + */ + void enterPointerType(GoParser.PointerTypeContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#pointerType}. + * @param ctx the parse tree + */ + void exitPointerType(GoParser.PointerTypeContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#interfaceType}. + * @param ctx the parse tree + */ + void enterInterfaceType(GoParser.InterfaceTypeContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#interfaceType}. + * @param ctx the parse tree + */ + void exitInterfaceType(GoParser.InterfaceTypeContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#sliceType}. + * @param ctx the parse tree + */ + void enterSliceType(GoParser.SliceTypeContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#sliceType}. + * @param ctx the parse tree + */ + void exitSliceType(GoParser.SliceTypeContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#mapType}. + * @param ctx the parse tree + */ + void enterMapType(GoParser.MapTypeContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#mapType}. + * @param ctx the parse tree + */ + void exitMapType(GoParser.MapTypeContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#channelType}. + * @param ctx the parse tree + */ + void enterChannelType(GoParser.ChannelTypeContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#channelType}. + * @param ctx the parse tree + */ + void exitChannelType(GoParser.ChannelTypeContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#methodSpec}. + * @param ctx the parse tree + */ + void enterMethodSpec(GoParser.MethodSpecContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#methodSpec}. + * @param ctx the parse tree + */ + void exitMethodSpec(GoParser.MethodSpecContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#functionType}. + * @param ctx the parse tree + */ + void enterFunctionType(GoParser.FunctionTypeContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#functionType}. + * @param ctx the parse tree + */ + void exitFunctionType(GoParser.FunctionTypeContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#signature}. + * @param ctx the parse tree + */ + void enterSignature(GoParser.SignatureContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#signature}. + * @param ctx the parse tree + */ + void exitSignature(GoParser.SignatureContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#result}. + * @param ctx the parse tree + */ + void enterResult(GoParser.ResultContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#result}. + * @param ctx the parse tree + */ + void exitResult(GoParser.ResultContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#parameters}. + * @param ctx the parse tree + */ + void enterParameters(GoParser.ParametersContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#parameters}. + * @param ctx the parse tree + */ + void exitParameters(GoParser.ParametersContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#parameterDecl}. + * @param ctx the parse tree + */ + void enterParameterDecl(GoParser.ParameterDeclContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#parameterDecl}. + * @param ctx the parse tree + */ + void exitParameterDecl(GoParser.ParameterDeclContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#expression}. + * @param ctx the parse tree + */ + void enterExpression(GoParser.ExpressionContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#expression}. + * @param ctx the parse tree + */ + void exitExpression(GoParser.ExpressionContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#primaryExpr}. + * @param ctx the parse tree + */ + void enterPrimaryExpr(GoParser.PrimaryExprContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#primaryExpr}. + * @param ctx the parse tree + */ + void exitPrimaryExpr(GoParser.PrimaryExprContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#conversion}. + * @param ctx the parse tree + */ + void enterConversion(GoParser.ConversionContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#conversion}. + * @param ctx the parse tree + */ + void exitConversion(GoParser.ConversionContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#operand}. + * @param ctx the parse tree + */ + void enterOperand(GoParser.OperandContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#operand}. + * @param ctx the parse tree + */ + void exitOperand(GoParser.OperandContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#literal}. + * @param ctx the parse tree + */ + void enterLiteral(GoParser.LiteralContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#literal}. + * @param ctx the parse tree + */ + void exitLiteral(GoParser.LiteralContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#basicLit}. + * @param ctx the parse tree + */ + void enterBasicLit(GoParser.BasicLitContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#basicLit}. + * @param ctx the parse tree + */ + void exitBasicLit(GoParser.BasicLitContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#integer}. + * @param ctx the parse tree + */ + void enterInteger(GoParser.IntegerContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#integer}. + * @param ctx the parse tree + */ + void exitInteger(GoParser.IntegerContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#operandName}. + * @param ctx the parse tree + */ + void enterOperandName(GoParser.OperandNameContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#operandName}. + * @param ctx the parse tree + */ + void exitOperandName(GoParser.OperandNameContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#qualifiedIdent}. + * @param ctx the parse tree + */ + void enterQualifiedIdent(GoParser.QualifiedIdentContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#qualifiedIdent}. + * @param ctx the parse tree + */ + void exitQualifiedIdent(GoParser.QualifiedIdentContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#compositeLit}. + * @param ctx the parse tree + */ + void enterCompositeLit(GoParser.CompositeLitContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#compositeLit}. + * @param ctx the parse tree + */ + void exitCompositeLit(GoParser.CompositeLitContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#literalType}. + * @param ctx the parse tree + */ + void enterLiteralType(GoParser.LiteralTypeContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#literalType}. + * @param ctx the parse tree + */ + void exitLiteralType(GoParser.LiteralTypeContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#literalValue}. + * @param ctx the parse tree + */ + void enterLiteralValue(GoParser.LiteralValueContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#literalValue}. + * @param ctx the parse tree + */ + void exitLiteralValue(GoParser.LiteralValueContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#elementList}. + * @param ctx the parse tree + */ + void enterElementList(GoParser.ElementListContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#elementList}. + * @param ctx the parse tree + */ + void exitElementList(GoParser.ElementListContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#keyedElement}. + * @param ctx the parse tree + */ + void enterKeyedElement(GoParser.KeyedElementContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#keyedElement}. + * @param ctx the parse tree + */ + void exitKeyedElement(GoParser.KeyedElementContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#key}. + * @param ctx the parse tree + */ + void enterKey(GoParser.KeyContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#key}. + * @param ctx the parse tree + */ + void exitKey(GoParser.KeyContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#element}. + * @param ctx the parse tree + */ + void enterElement(GoParser.ElementContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#element}. + * @param ctx the parse tree + */ + void exitElement(GoParser.ElementContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#structType}. + * @param ctx the parse tree + */ + void enterStructType(GoParser.StructTypeContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#structType}. + * @param ctx the parse tree + */ + void exitStructType(GoParser.StructTypeContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#fieldDecl}. + * @param ctx the parse tree + */ + void enterFieldDecl(GoParser.FieldDeclContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#fieldDecl}. + * @param ctx the parse tree + */ + void exitFieldDecl(GoParser.FieldDeclContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#string_}. + * @param ctx the parse tree + */ + void enterString_(GoParser.String_Context ctx); + /** + * Exit a parse tree produced by {@link GoParser#string_}. + * @param ctx the parse tree + */ + void exitString_(GoParser.String_Context ctx); + /** + * Enter a parse tree produced by {@link GoParser#embeddedField}. + * @param ctx the parse tree + */ + void enterEmbeddedField(GoParser.EmbeddedFieldContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#embeddedField}. + * @param ctx the parse tree + */ + void exitEmbeddedField(GoParser.EmbeddedFieldContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#functionLit}. + * @param ctx the parse tree + */ + void enterFunctionLit(GoParser.FunctionLitContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#functionLit}. + * @param ctx the parse tree + */ + void exitFunctionLit(GoParser.FunctionLitContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#index}. + * @param ctx the parse tree + */ + void enterIndex(GoParser.IndexContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#index}. + * @param ctx the parse tree + */ + void exitIndex(GoParser.IndexContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#slice_}. + * @param ctx the parse tree + */ + void enterSlice_(GoParser.Slice_Context ctx); + /** + * Exit a parse tree produced by {@link GoParser#slice_}. + * @param ctx the parse tree + */ + void exitSlice_(GoParser.Slice_Context ctx); + /** + * Enter a parse tree produced by {@link GoParser#typeAssertion}. + * @param ctx the parse tree + */ + void enterTypeAssertion(GoParser.TypeAssertionContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#typeAssertion}. + * @param ctx the parse tree + */ + void exitTypeAssertion(GoParser.TypeAssertionContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#arguments}. + * @param ctx the parse tree + */ + void enterArguments(GoParser.ArgumentsContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#arguments}. + * @param ctx the parse tree + */ + void exitArguments(GoParser.ArgumentsContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#methodExpr}. + * @param ctx the parse tree + */ + void enterMethodExpr(GoParser.MethodExprContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#methodExpr}. + * @param ctx the parse tree + */ + void exitMethodExpr(GoParser.MethodExprContext ctx); + /** + * Enter a parse tree produced by {@link GoParser#eos}. + * @param ctx the parse tree + */ + void enterEos(GoParser.EosContext ctx); + /** + * Exit a parse tree produced by {@link GoParser#eos}. + * @param ctx the parse tree + */ + void exitEos(GoParser.EosContext ctx); +} \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/ParseResult.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/ParseResult.java new file mode 100644 index 000000000..f9ddc0b83 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/antlr/golang/ParseResult.java @@ -0,0 +1,22 @@ +package run.mone.antlr.golang; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2024/2/1 22:48 + */ +@Data +@Builder +public class ParseResult { + + + private List fieldList; + + private Map> methodMap; + +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/controller/TestController.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/controller/TestController.java new file mode 100644 index 000000000..3c82b0e34 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/controller/TestController.java @@ -0,0 +1,29 @@ +package run.mone.z.desensitization.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import run.mone.z.desensitization.domain.gateway.DemoGateway; +import run.mone.z.desensitization.domain.model.DemoReqEntiry; + +/** + * @author wm + */ +@RestController +public class TestController { + + @Autowired + private DemoGateway demoGateway; + + @ResponseBody + @RequestMapping(value = "/md5", method = RequestMethod.GET) + public String getStr(){ + DemoReqEntiry req = new DemoReqEntiry(); + req.setTest("abc"); + return demoGateway.demoTest(req).getTest(); + } + + +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/dto/DesensitizeRsp.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/dto/DesensitizeRsp.java new file mode 100644 index 000000000..e404ebcd7 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/dto/DesensitizeRsp.java @@ -0,0 +1,22 @@ +package run.mone.z.desensitization.dto; + +import lombok.Builder; +import lombok.Data; + +/** + * @author wmin + * @date 2024/1/31 + */ +@Data +@Builder +public class DesensitizeRsp { + private String textBefore; + + private String textAfter; + + private String username; + + private int status; + + private long durationTime; +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/mapper/ZDesensitizationRecordMapper.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/mapper/ZDesensitizationRecordMapper.java new file mode 100644 index 000000000..758ef6e45 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/mapper/ZDesensitizationRecordMapper.java @@ -0,0 +1,40 @@ +package run.mone.z.desensitization.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import run.mone.z.desensitization.pojo.ZDesensitizationRecord; +import run.mone.z.desensitization.pojo.ZDesensitizationRecordExample; + +public interface ZDesensitizationRecordMapper { + long countByExample(ZDesensitizationRecordExample example); + + int deleteByExample(ZDesensitizationRecordExample example); + + int deleteByPrimaryKey(Long id); + + int insert(ZDesensitizationRecord record); + + int insertSelective(ZDesensitizationRecord record); + + List selectByExampleWithBLOBs(ZDesensitizationRecordExample example); + + List selectByExample(ZDesensitizationRecordExample example); + + ZDesensitizationRecord selectByPrimaryKey(Long id); + + int updateByExampleSelective(@Param("record") ZDesensitizationRecord record, @Param("example") ZDesensitizationRecordExample example); + + int updateByExampleWithBLOBs(@Param("record") ZDesensitizationRecord record, @Param("example") ZDesensitizationRecordExample example); + + int updateByExample(@Param("record") ZDesensitizationRecord record, @Param("example") ZDesensitizationRecordExample example); + + int updateByPrimaryKeySelective(ZDesensitizationRecord record); + + int updateByPrimaryKeyWithBLOBs(ZDesensitizationRecord record); + + int updateByPrimaryKey(ZDesensitizationRecord record); + + int batchInsert(@Param("list") List list); + + int batchInsertSelective(@Param("list") List list, @Param("selective") ZDesensitizationRecord.Column ... selective); +} \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/pojo/ZDesensitizationRecord.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/pojo/ZDesensitizationRecord.java new file mode 100644 index 000000000..82e555caa --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/pojo/ZDesensitizationRecord.java @@ -0,0 +1,154 @@ +package run.mone.z.desensitization.pojo; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; + +public class ZDesensitizationRecord { + private Long id; + + private Date gmtCreate; + + private String creator; + + private Integer status; + + private Long durationTime; + + private String textBefore; + + private String textAfter; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Date getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Date gmtCreate) { + this.gmtCreate = gmtCreate; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator == null ? null : creator.trim(); + } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } + + public Long getDurationTime() { + return durationTime; + } + + public void setDurationTime(Long durationTime) { + this.durationTime = durationTime; + } + + public String getTextBefore() { + return textBefore; + } + + public void setTextBefore(String textBefore) { + this.textBefore = textBefore == null ? null : textBefore.trim(); + } + + public String getTextAfter() { + return textAfter; + } + + public void setTextAfter(String textAfter) { + this.textAfter = textAfter == null ? null : textAfter.trim(); + } + + public enum Column { + id("id", "id", "BIGINT", false), + gmtCreate("gmt_create", "gmtCreate", "TIMESTAMP", false), + creator("creator", "creator", "VARCHAR", false), + status("status", "status", "INTEGER", false), + durationTime("duration_time", "durationTime", "BIGINT", false), + textBefore("text_before", "textBefore", "LONGVARCHAR", false), + textAfter("text_after", "textAfter", "LONGVARCHAR", false); + + private static final String BEGINNING_DELIMITER = "\""; + + private static final String ENDING_DELIMITER = "\""; + + private final String column; + + private final boolean isColumnNameDelimited; + + private final String javaProperty; + + private final String jdbcType; + + public String value() { + return this.column; + } + + public String getValue() { + return this.column; + } + + public String getJavaProperty() { + return this.javaProperty; + } + + public String getJdbcType() { + return this.jdbcType; + } + + Column(String column, String javaProperty, String jdbcType, boolean isColumnNameDelimited) { + this.column = column; + this.javaProperty = javaProperty; + this.jdbcType = jdbcType; + this.isColumnNameDelimited = isColumnNameDelimited; + } + + public String desc() { + return this.getEscapedColumnName() + " DESC"; + } + + public String asc() { + return this.getEscapedColumnName() + " ASC"; + } + + public static Column[] excludes(Column ... excludes) { + ArrayList columns = new ArrayList<>(Arrays.asList(Column.values())); + if (excludes != null && excludes.length > 0) { + columns.removeAll(new ArrayList<>(Arrays.asList(excludes))); + } + return columns.toArray(new Column[]{}); + } + + public static Column[] all() { + return Column.values(); + } + + public String getEscapedColumnName() { + if (this.isColumnNameDelimited) { + return new StringBuilder().append(BEGINNING_DELIMITER).append(this.column).append(ENDING_DELIMITER).toString(); + } else { + return this.column; + } + } + + public String getAliasedEscapedColumnName() { + return this.getEscapedColumnName(); + } + } +} \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/pojo/ZDesensitizationRecordExample.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/pojo/ZDesensitizationRecordExample.java new file mode 100644 index 000000000..2145a11c9 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/pojo/ZDesensitizationRecordExample.java @@ -0,0 +1,511 @@ +package run.mone.z.desensitization.pojo; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class ZDesensitizationRecordExample { + protected String orderByClause; + + protected boolean distinct; + + protected List oredCriteria; + + public ZDesensitizationRecordExample() { + oredCriteria = new ArrayList(); + } + + public void setOrderByClause(String orderByClause) { + this.orderByClause = orderByClause; + } + + public String getOrderByClause() { + return orderByClause; + } + + public void setDistinct(boolean distinct) { + this.distinct = distinct; + } + + public boolean isDistinct() { + return distinct; + } + + public List getOredCriteria() { + return oredCriteria; + } + + public void or(Criteria criteria) { + oredCriteria.add(criteria); + } + + public Criteria or() { + Criteria criteria = createCriteriaInternal(); + oredCriteria.add(criteria); + return criteria; + } + + public Criteria createCriteria() { + Criteria criteria = createCriteriaInternal(); + if (oredCriteria.size() == 0) { + oredCriteria.add(criteria); + } + return criteria; + } + + protected Criteria createCriteriaInternal() { + Criteria criteria = new Criteria(); + return criteria; + } + + public void clear() { + oredCriteria.clear(); + orderByClause = null; + distinct = false; + } + + protected abstract static class GeneratedCriteria { + protected List criteria; + + protected GeneratedCriteria() { + super(); + criteria = new ArrayList(); + } + + public boolean isValid() { + return criteria.size() > 0; + } + + public List getAllCriteria() { + return criteria; + } + + public List getCriteria() { + return criteria; + } + + protected void addCriterion(String condition) { + if (condition == null) { + throw new RuntimeException("Value for condition cannot be null"); + } + criteria.add(new Criterion(condition)); + } + + protected void addCriterion(String condition, Object value, String property) { + if (value == null) { + throw new RuntimeException("Value for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value)); + } + + protected void addCriterion(String condition, Object value1, Object value2, String property) { + if (value1 == null || value2 == null) { + throw new RuntimeException("Between values for " + property + " cannot be null"); + } + criteria.add(new Criterion(condition, value1, value2)); + } + + public Criteria andIdIsNull() { + addCriterion("id is null"); + return (Criteria) this; + } + + public Criteria andIdIsNotNull() { + addCriterion("id is not null"); + return (Criteria) this; + } + + public Criteria andIdEqualTo(Long value) { + addCriterion("id =", value, "id"); + return (Criteria) this; + } + + public Criteria andIdNotEqualTo(Long value) { + addCriterion("id <>", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThan(Long value) { + addCriterion("id >", value, "id"); + return (Criteria) this; + } + + public Criteria andIdGreaterThanOrEqualTo(Long value) { + addCriterion("id >=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThan(Long value) { + addCriterion("id <", value, "id"); + return (Criteria) this; + } + + public Criteria andIdLessThanOrEqualTo(Long value) { + addCriterion("id <=", value, "id"); + return (Criteria) this; + } + + public Criteria andIdIn(List values) { + addCriterion("id in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdNotIn(List values) { + addCriterion("id not in", values, "id"); + return (Criteria) this; + } + + public Criteria andIdBetween(Long value1, Long value2) { + addCriterion("id between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andIdNotBetween(Long value1, Long value2) { + addCriterion("id not between", value1, value2, "id"); + return (Criteria) this; + } + + public Criteria andGmtCreateIsNull() { + addCriterion("gmt_create is null"); + return (Criteria) this; + } + + public Criteria andGmtCreateIsNotNull() { + addCriterion("gmt_create is not null"); + return (Criteria) this; + } + + public Criteria andGmtCreateEqualTo(Date value) { + addCriterion("gmt_create =", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateNotEqualTo(Date value) { + addCriterion("gmt_create <>", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateGreaterThan(Date value) { + addCriterion("gmt_create >", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateGreaterThanOrEqualTo(Date value) { + addCriterion("gmt_create >=", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateLessThan(Date value) { + addCriterion("gmt_create <", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateLessThanOrEqualTo(Date value) { + addCriterion("gmt_create <=", value, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateIn(List values) { + addCriterion("gmt_create in", values, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateNotIn(List values) { + addCriterion("gmt_create not in", values, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateBetween(Date value1, Date value2) { + addCriterion("gmt_create between", value1, value2, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andGmtCreateNotBetween(Date value1, Date value2) { + addCriterion("gmt_create not between", value1, value2, "gmtCreate"); + return (Criteria) this; + } + + public Criteria andCreatorIsNull() { + addCriterion("creator is null"); + return (Criteria) this; + } + + public Criteria andCreatorIsNotNull() { + addCriterion("creator is not null"); + return (Criteria) this; + } + + public Criteria andCreatorEqualTo(String value) { + addCriterion("creator =", value, "creator"); + return (Criteria) this; + } + + public Criteria andCreatorNotEqualTo(String value) { + addCriterion("creator <>", value, "creator"); + return (Criteria) this; + } + + public Criteria andCreatorGreaterThan(String value) { + addCriterion("creator >", value, "creator"); + return (Criteria) this; + } + + public Criteria andCreatorGreaterThanOrEqualTo(String value) { + addCriterion("creator >=", value, "creator"); + return (Criteria) this; + } + + public Criteria andCreatorLessThan(String value) { + addCriterion("creator <", value, "creator"); + return (Criteria) this; + } + + public Criteria andCreatorLessThanOrEqualTo(String value) { + addCriterion("creator <=", value, "creator"); + return (Criteria) this; + } + + public Criteria andCreatorLike(String value) { + addCriterion("creator like", value, "creator"); + return (Criteria) this; + } + + public Criteria andCreatorNotLike(String value) { + addCriterion("creator not like", value, "creator"); + return (Criteria) this; + } + + public Criteria andCreatorIn(List values) { + addCriterion("creator in", values, "creator"); + return (Criteria) this; + } + + public Criteria andCreatorNotIn(List values) { + addCriterion("creator not in", values, "creator"); + return (Criteria) this; + } + + public Criteria andCreatorBetween(String value1, String value2) { + addCriterion("creator between", value1, value2, "creator"); + return (Criteria) this; + } + + public Criteria andCreatorNotBetween(String value1, String value2) { + addCriterion("creator not between", value1, value2, "creator"); + return (Criteria) this; + } + + public Criteria andStatusIsNull() { + addCriterion("status is null"); + return (Criteria) this; + } + + public Criteria andStatusIsNotNull() { + addCriterion("status is not null"); + return (Criteria) this; + } + + public Criteria andStatusEqualTo(Integer value) { + addCriterion("status =", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusNotEqualTo(Integer value) { + addCriterion("status <>", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusGreaterThan(Integer value) { + addCriterion("status >", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusGreaterThanOrEqualTo(Integer value) { + addCriterion("status >=", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusLessThan(Integer value) { + addCriterion("status <", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusLessThanOrEqualTo(Integer value) { + addCriterion("status <=", value, "status"); + return (Criteria) this; + } + + public Criteria andStatusIn(List values) { + addCriterion("status in", values, "status"); + return (Criteria) this; + } + + public Criteria andStatusNotIn(List values) { + addCriterion("status not in", values, "status"); + return (Criteria) this; + } + + public Criteria andStatusBetween(Integer value1, Integer value2) { + addCriterion("status between", value1, value2, "status"); + return (Criteria) this; + } + + public Criteria andStatusNotBetween(Integer value1, Integer value2) { + addCriterion("status not between", value1, value2, "status"); + return (Criteria) this; + } + + public Criteria andDurationTimeIsNull() { + addCriterion("duration_time is null"); + return (Criteria) this; + } + + public Criteria andDurationTimeIsNotNull() { + addCriterion("duration_time is not null"); + return (Criteria) this; + } + + public Criteria andDurationTimeEqualTo(Long value) { + addCriterion("duration_time =", value, "durationTime"); + return (Criteria) this; + } + + public Criteria andDurationTimeNotEqualTo(Long value) { + addCriterion("duration_time <>", value, "durationTime"); + return (Criteria) this; + } + + public Criteria andDurationTimeGreaterThan(Long value) { + addCriterion("duration_time >", value, "durationTime"); + return (Criteria) this; + } + + public Criteria andDurationTimeGreaterThanOrEqualTo(Long value) { + addCriterion("duration_time >=", value, "durationTime"); + return (Criteria) this; + } + + public Criteria andDurationTimeLessThan(Long value) { + addCriterion("duration_time <", value, "durationTime"); + return (Criteria) this; + } + + public Criteria andDurationTimeLessThanOrEqualTo(Long value) { + addCriterion("duration_time <=", value, "durationTime"); + return (Criteria) this; + } + + public Criteria andDurationTimeIn(List values) { + addCriterion("duration_time in", values, "durationTime"); + return (Criteria) this; + } + + public Criteria andDurationTimeNotIn(List values) { + addCriterion("duration_time not in", values, "durationTime"); + return (Criteria) this; + } + + public Criteria andDurationTimeBetween(Long value1, Long value2) { + addCriterion("duration_time between", value1, value2, "durationTime"); + return (Criteria) this; + } + + public Criteria andDurationTimeNotBetween(Long value1, Long value2) { + addCriterion("duration_time not between", value1, value2, "durationTime"); + return (Criteria) this; + } + } + + public static class Criteria extends GeneratedCriteria { + + protected Criteria() { + super(); + } + } + + public static class Criterion { + private String condition; + + private Object value; + + private Object secondValue; + + private boolean noValue; + + private boolean singleValue; + + private boolean betweenValue; + + private boolean listValue; + + private String typeHandler; + + public String getCondition() { + return condition; + } + + public Object getValue() { + return value; + } + + public Object getSecondValue() { + return secondValue; + } + + public boolean isNoValue() { + return noValue; + } + + public boolean isSingleValue() { + return singleValue; + } + + public boolean isBetweenValue() { + return betweenValue; + } + + public boolean isListValue() { + return listValue; + } + + public String getTypeHandler() { + return typeHandler; + } + + protected Criterion(String condition) { + super(); + this.condition = condition; + this.typeHandler = null; + this.noValue = true; + } + + protected Criterion(String condition, Object value, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.typeHandler = typeHandler; + if (value instanceof List) { + this.listValue = true; + } else { + this.singleValue = true; + } + } + + protected Criterion(String condition, Object value) { + this(condition, value, null); + } + + protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { + super(); + this.condition = condition; + this.value = value; + this.secondValue = secondValue; + this.typeHandler = typeHandler; + this.betweenValue = true; + } + + protected Criterion(String condition, Object value, Object secondValue) { + this(condition, value, secondValue, null); + } + } +} \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/AiCodeDesensitizeService.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/AiCodeDesensitizeService.java new file mode 100644 index 000000000..7d76fe0ca --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/AiCodeDesensitizeService.java @@ -0,0 +1,49 @@ +package run.mone.z.desensitization.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.xiaomi.sautumn.serverless.api.http.Http; +import com.xiaomi.sautumn.serverless.api.http.HttpResult; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +/** + * @author wmin + * @date 2023/11/20 + */ +@Service +@Slf4j +public class AiCodeDesensitizeService { + + @Resource + private Http http; + + public String aiCodeDesensitize(String code){ + String res = code; + try { + log.info("aiCodeDesensitize start"); + Map map = new HashMap<>(); + map.put("data",code); + HttpResult httpResult = http.postForm("http://localhost/desensitize_form",map,new HashMap() {{ + put("content-type", "application/x-www-form-urlencoded"); + }},"utf-8", 5000); + if (200==httpResult.getCode() && StringUtils.isNotBlank(httpResult.getContent())){ + JSONObject jsonObject = JSON.parseObject(httpResult.getContent()); + if (0==jsonObject.getInteger("code") && StringUtils.isNotBlank(jsonObject.getString("data"))){ + res = jsonObject.getString("data"); + log.info("aiCodeDesensitize done.{}", res); + } + } else { + log.error("aiCodeDesensitize failed.{}", httpResult); + } + } catch (Exception e){ + log.error("aiCodeDesensitize error.", e); + } + return res; + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/CodeDesensitizeServiceImpl.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/CodeDesensitizeServiceImpl.java new file mode 100644 index 000000000..b3368bdec --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/CodeDesensitizeServiceImpl.java @@ -0,0 +1,169 @@ +package run.mone.z.desensitization.service; + +import com.google.common.base.Preconditions; +import com.google.gson.Gson; +import com.xiaomi.youpin.infra.rpc.Result; +import com.xiaomi.youpin.infra.rpc.errors.GeneralCodes; +import io.netty.handler.codec.http.HttpResponseStatus; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import run.mone.sautumnn.springboot.starter.anno.DubboService; +import run.mone.z.desensitization.api.bo.DesensitizeReq; +import run.mone.z.desensitization.api.service.CodeDesensitizeService; +import run.mone.z.desensitization.dto.DesensitizeRsp; +import run.mone.z.desensitization.service.common.CodeDesensitizeUtils; +import run.mone.z.desensitization.service.common.CodeExtractorUtils; +import run.mone.z.desensitization.service.common.Consts; +import run.mone.z.desensitization.service.common.NewCodeDesensitizeUtils; + +import javax.annotation.Resource; + +/** + * @author wmin + * @date 2023/6/5 + */ +@DubboService(interfaceClass = CodeDesensitizeService.class, timeout = 5000, group = "${dubbo.group}", version = "1.0") +@Slf4j +public class CodeDesensitizeServiceImpl implements CodeDesensitizeService { + + @Resource + private AiCodeDesensitizeService aiCodeDesensitizeService; + + @Resource + private RecordService recordService; + + private Gson gson = new Gson(); + @Override + public Result codeDesensitize(String codeSnippet) { + try { + String codeSnippetAfterDesensitized = CodeDesensitizeUtils.codeDesensitizeForClass(codeSnippet); + if (StringUtils.isNoneBlank(codeSnippetAfterDesensitized)){ + return Result.success(codeSnippetAfterDesensitized); + } + return Result.fail(GeneralCodes.ParamError, "The code does not comply with the syntax requirements"); + } catch (Exception e) { + log.error("codeDesensitize error.", e); + return Result.fail(GeneralCodes.InternalError, HttpResponseStatus.INTERNAL_SERVER_ERROR.reasonPhrase()); + } + } + + public Result codeDesensitizeWithSpecConfig(DesensitizeReq req) { + try { + if (StringUtils.isBlank(req.getLangType())) { + log.warn("lang type is not specified! currently supported: java / go; WILL USE: java as lang type to desensitize!"); + req.setLangType(Consts.LANG_JAVA); + } + String codeSnippetAfterDesensitized = req.getText(); + switch (req.getLangType()) { + case Consts.LANG_GO: + codeSnippetAfterDesensitized = NewCodeDesensitizeUtils.codeDesensitizeForGo(req); + break; + case Consts.LANG_JAVA: + default: + codeSnippetAfterDesensitized = NewCodeDesensitizeUtils.codeDesensitizeForClass(req); + } + if (StringUtils.isNoneBlank(codeSnippetAfterDesensitized)){ + return Result.success(codeSnippetAfterDesensitized); + } + return Result.fail(GeneralCodes.ParamError, "The code does not comply with the syntax requirements"); + } catch (Exception e) { + log.error("codeDesensitize error.", e); + return Result.fail(GeneralCodes.InternalError, HttpResponseStatus.INTERNAL_SERVER_ERROR.reasonPhrase()); + } + } + + @Override + public Result textDesensitize(String text) { + try { + Pair rst = CodeExtractorUtils.codeExtractor(text); + if (rst.getKey()){ + String[] index = rst.getValue().split("-"); + String codeSnippet = text.substring(Integer.parseInt(index[0]), Integer.parseInt(index[1])+1); + Result codeRst = codeDesensitize(codeSnippet); + if (codeRst.getCode()==0){ + StringBuilder sb = new StringBuilder(text); + sb.replace(Integer.parseInt(index[0]), Integer.parseInt(index[1])+2, codeRst.getData()); + return Result.success(sb.toString()); + } + return codeRst; + } + return Result.fail(GeneralCodes.ParamError, "codeExtractor error"); + } catch (Exception e) { + log.error("textDesensitize error.", e); + return Result.fail(GeneralCodes.InternalError, HttpResponseStatus.INTERNAL_SERVER_ERROR.reasonPhrase()); + } + } + + @Override + public Result textDesensitizeWithAi(DesensitizeReq req) { + long startTime = System.currentTimeMillis(); + Result rst = null; + DesensitizeRsp rsp = DesensitizeRsp.builder() + .textBefore(req.getText()) + .username(req.getUsername()) + .build(); + try { + rst = textDesensitizeWithAiBase(req); + return rst; + } finally { + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + rsp.setDurationTime(duration); + rsp.setStatus(rst.getCode()==0?1:0); + rsp.setTextAfter(rst.getData()); + log.info("textDesensitizeWithAi status:{},duration:{}", rsp.getStatus(), duration); + recordService.saveRecord(rsp); + } + } + + public Result textDesensitizeWithAiBase(DesensitizeReq req) { + log.info("textDesensitizeWithAi req:{}", gson.toJson(req)); + Preconditions.checkArgument(null!=req && StringUtils.isNotBlank(req.getText()), "text can not be null"); + String text = req.getText(); + Boolean aiFlag = req.getAiDesensitizeFlag(); + //保险起见,默认本地失败,只要失败就调ai + Boolean isLocalFailed = true; + String textAfterDe = text; + + try { + // 如果需要提取代码,则提取; 否则直接脱敏 + if (req.getNeedExtract() != null && Boolean.TRUE.equals(req.getNeedExtract())) { + Pair rst = CodeExtractorUtils.codeExtractorWithLabel(text); + log.info("Perform code extraction with res:{}", rst); + if (rst.getKey()) { + String[] index = rst.getValue().split("-"); + String codeSnippet = text.substring(Integer.parseInt(index[0]), Integer.parseInt(index[1])); + log.info("codeSnippet after codeExtractorWithLabel:{}", codeSnippet); + req.setText(codeSnippet); + Result codeRst = codeDesensitizeWithSpecConfig(req); + if (codeRst.getCode() == 0) { + StringBuilder sb = new StringBuilder(text); + sb.replace(Integer.parseInt(index[0]), Integer.parseInt(index[1]) + 1, codeRst.getData()); + isLocalFailed = false; + textAfterDe = sb.toString(); + } + } else { + log.error("local textDesensitizeWithAi failed."); + } + } else { + log.info("Perform desensitization directly with req!"); + Result codeRst = codeDesensitizeWithSpecConfig(req); + isLocalFailed = false; + textAfterDe = codeRst.getData(); + } + } catch (Exception e) { + log.error("textDesensitizeWithAi error.", e); + } + //if (BooleanUtils.isTrue(isLocalFailed) || BooleanUtils.isTrue(aiFlag)){ + if (BooleanUtils.isTrue(aiFlag)){ + //call ai http + textAfterDe = aiCodeDesensitizeService.aiCodeDesensitize(textAfterDe); + } + if (BooleanUtils.isTrue(isLocalFailed) && BooleanUtils.isFalse(aiFlag)){ + return Result.fail(GeneralCodes.InternalError, "local desensitization failed, and is configured not to call AI desensitization!"); + } + return Result.success(textAfterDe); + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/DubboHealthServiceImpl.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/DubboHealthServiceImpl.java new file mode 100644 index 000000000..c5bd9ee22 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/DubboHealthServiceImpl.java @@ -0,0 +1,16 @@ +package run.mone.z.desensitization.service; + +import com.xiaomi.youpin.infra.rpc.Result; +import lombok.extern.slf4j.Slf4j; +import run.mone.sautumnn.springboot.starter.anno.DubboService; +import run.mone.z.desensitization.api.service.DubboHealthService; + +@DubboService(interfaceClass = DubboHealthService.class, timeout = 1000, group = "${dubbo.group}", version = "1.0") +@Slf4j +public class DubboHealthServiceImpl implements DubboHealthService { + + @Override + public Result health() { + return Result.success("ok"); + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/RecordService.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/RecordService.java new file mode 100644 index 000000000..0bfffe4a3 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/RecordService.java @@ -0,0 +1,37 @@ +package run.mone.z.desensitization.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import run.mone.z.desensitization.dto.DesensitizeRsp; +import run.mone.z.desensitization.mapper.ZDesensitizationRecordMapper; +import run.mone.z.desensitization.pojo.ZDesensitizationRecord; + +import javax.annotation.Resource; +import java.util.Date; + +/** + * @author wmin + * @date 2024/1/31 + */ +@Slf4j +@Service +public class RecordService { + + @Resource + private ZDesensitizationRecordMapper recordMapper; + + public void saveRecord(DesensitizeRsp rsp) { + try { + ZDesensitizationRecord record = new ZDesensitizationRecord(); + record.setGmtCreate(new Date()); + record.setCreator(rsp.getUsername()); + record.setTextBefore(rsp.getTextBefore()); + record.setTextAfter(rsp.getTextAfter()); + record.setStatus(rsp.getStatus()); + record.setDurationTime(rsp.getDurationTime()); + log.info("saveRecord :{}", recordMapper.insert(record)); + } catch (Exception e) { + log.error("saveRecord", e); + } + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/ClassUtils.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/ClassUtils.java new file mode 100644 index 000000000..28a591232 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/ClassUtils.java @@ -0,0 +1,57 @@ +package run.mone.z.desensitization.service.common; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ast.CompilationUnit; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.util.JavacTask; +import com.sun.source.util.Trees; +import com.sun.tools.javac.api.JavacTool; + +import javax.tools.*; +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; + +/** + * @author wmin + * @date 2023/6/5 + * 解析class语法树 + */ +public class ClassUtils { + + public static CompilationUnitTree getUnitTreeWithClassName(String sourceCode, String className) throws IOException { + JavaCompiler compiler = JavacTool.create(); + StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); + JavaFileObject sourceFile = new JavaSourceFromString(className, sourceCode); + // 设置虚拟源文件的存储位置 + fileManager.setLocation(StandardLocation.CLASS_PATH, Arrays.asList()); + // 编译源代码 + JavacTask task = (JavacTask) compiler.getTask(null, fileManager, null, null, null, Arrays.asList(sourceFile)); + // 获取编译单元树 + Trees trees = Trees.instance(task); + Iterable compilationUnits = task.parse(); + CompilationUnitTree compilationUnit = compilationUnits.iterator().next(); + // 关闭文件管理器 + fileManager.close(); + return compilationUnit; + } + + private static CompilationUnit getUnitTree(String sourceCode){ + JavaParser javaParser = new JavaParser(); + CompilationUnit compilationUnit = javaParser.parse(sourceCode).getResult().get(); + return compilationUnit; + } + + // 自定义Java源文件对象 + static class JavaSourceFromString extends SimpleJavaFileObject { + final String code; + JavaSourceFromString(String name, String code) { + super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE); + this.code = code; + } + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return code; + } + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeDesensitizeUtils.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeDesensitizeUtils.java new file mode 100644 index 000000000..a67de7c4e --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeDesensitizeUtils.java @@ -0,0 +1,214 @@ +package run.mone.z.desensitization.service.common; + +import com.google.common.collect.Sets; +import com.sun.source.tree.*; +import com.sun.source.util.TreeScanner; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.util.Context; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import run.mone.z.desensitization.api.common.CodeTypeEnum; + +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +import static run.mone.z.desensitization.service.common.Consts.*; + +/** + * @author wmin + * @date 2023/6/5 + * 代码脱敏 + */ +@Slf4j +public class CodeDesensitizeUtils { + + /** + * 敏感词key + */ + private static Set filedOrMethodNames = Sets.newHashSet("password", "pwd", "secret", "token", "ip", "host"); + + private static Set ipKeys = Sets.newHashSet( "ip", "host"); + /** + * IP白名单 + */ + private static Set ipWhite = Sets.newHashSet("127.0.0.1", "0.0.0.0"); + + private static TreeScanner scanner; + + public static String codeDesensitizeForClass(String sourceCode, String className) throws Exception { + CompilationUnitTree compilationUnit = ClassUtils.getUnitTreeWithClassName(sourceCode, className); + TreeScanner scanner = getTreeScanner(); + scanner.scan(compilationUnit, null); + String codeAfterDesensitized = compilationUnit.toString(); + if (tmpClassName.equals(className)){ + codeAfterDesensitized = codeAfterDesensitized.substring(tmpClassNamePrefix.length()+1, codeAfterDesensitized.length()-1).replaceAll("^\\n+|\\n+$", ""); + } + log.info("codeAfterDesensitized ======{}======", codeAfterDesensitized); + return codeAfterDesensitized; + } + + public static String codeDesensitizeForClass(String sourceCode) throws Exception { + Pair rst = CodeParseUtils.codeParse(sourceCode); + if (rst!=null){ + if (CodeTypeEnum.CLASS.getType().equals(rst.getKey())){ + return codeDesensitizeForClass(sourceCode, rst.getValue()); + } + if (CodeTypeEnum.METHOD.getType().equals(rst.getKey())){ + return codeDesensitizeForClass(tmpClassNamePrefix + sourceCode + tmpClassNameSuffix, rst.getValue()); + } + } + return ""; + } + + private static synchronized TreeScanner getTreeScanner(){ + if (scanner!=null){ + return scanner; + } + Context context = new Context(); + JavacFileManager.preRegister(context); + TreeMaker treeMaker = TreeMaker.instance(context); + scanner = new TreeScanner() { + @Override + public Void visitVariable(VariableTree variableTree, Void aVoid) { + String key = variableTree.getName().toString(); + + //已初始化 + if (variableTree.getInitializer()!=null) { + ExpressionTree initializer = variableTree.getInitializer(); + if (initializer instanceof LiteralTree) { + String value = ((LiteralTree) initializer).getValue().toString(); + String valueDesensitized = value; + if (isSensitiveKey(key.toLowerCase())){ + valueDesensitized = maskValue(value, ipKeys.contains(key.toLowerCase())?"ip":"content"); + } + Pair valuePair = isSensitiveValue(value); + if (valuePair.getKey()){ + valueDesensitized = valuePair.getValue(); + } + JCTree.JCLiteral newLiteral = treeMaker.Literal(valueDesensitized); + ((JCTree.JCVariableDecl) variableTree).init = newLiteral; + } + } + return super.visitVariable(variableTree, aVoid); + } + + @Override + public Void visitMethod(MethodTree methodTreeTree, Void aVoid) { + BlockTree body = methodTreeTree.getBody(); + if (null != body) { + List stats = body.getStatements(); + stats.forEach(it -> { + if (it instanceof JCTree.JCExpressionStatement) { + JCTree.JCExpressionStatement statement = (JCTree.JCExpressionStatement) it; + JCTree.JCExpression expression = statement.getExpression(); + if (expression instanceof JCTree.JCMethodInvocation) { + JCTree.JCMethodInvocation invocation = (JCTree.JCMethodInvocation) expression; + com.sun.tools.javac.util.List arguments = invocation.getArguments(); + if (arguments.head!=null){ + com.sun.tools.javac.util.List newArguments = null; + for (int i =0;i pair = isSensitiveValue(value); + if (pair.getKey()){ + arg = treeMaker.Literal(pair.getValue()); + } + if (newArguments==null){ + newArguments = com.sun.tools.javac.util.List.of(arg); + } else { + newArguments = newArguments.append(arg); + } + } + if (arg instanceof JCTree.JCIdent) { + if (newArguments==null){ + newArguments = com.sun.tools.javac.util.List.of(arg); + } else { + newArguments = newArguments.append(arg); + } + } + } + invocation.args = newArguments; + } + } + } + }); + } + return super.visitMethod(methodTreeTree, aVoid); + } + }; + return scanner; + } + + + private static boolean isSensitiveKey(String key){ + //todo 只要包含就算,可能误判 + for (String keyword : filedOrMethodNames) { + if (key.toLowerCase().contains(keyword.toLowerCase())) { + return true; + } + } + return false; + } + + private static Pair isSensitiveValue(String value){ + Pair ipRst = hasSensitiveIP(value); + if (ipRst.getKey()){ + return ipRst; + } + Pair pwdRst = hasSensitivePwd(value); + return pwdRst; + } + + private static Pair hasSensitivePwd(String value){ + if (value.length() < 8) { + return Pair.of(false, value); + } + String specialCharacters = "!@#$%^&*()_-"; + boolean hasLetter = false; + boolean hasDigit = false; + boolean hasSpecialChar = false; + + for (char c : value.toCharArray()) { + if (Character.isLetter(c)) { + hasLetter = true; + } else if (Character.isDigit(c)) { + hasDigit = true; + } else { + if (specialCharacters.contains(String.valueOf(c))) { + hasSpecialChar = true; + } + } + } + //同时包含字母/数字/特殊字符 + if (hasLetter && hasDigit && hasSpecialChar){ + return Pair.of(true, maskValue(value, "value")); + } + + return Pair.of(false, value); + } + + private static Pair hasSensitiveIP(String value){ + String ipPattern = "^((\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\\.){3}(\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])$"; + if (!ipWhite.contains(value) && Pattern.matches(ipPattern, value)){ + return Pair.of(true, maskValue(value, "ip")); + } + return Pair.of(false, value); + } + + //对敏感信息进行脱敏 + private static String maskValue(String value, String type) { + if ("ip".equals(type)){ + if (ipWhite.contains(value)){ + return value; + } + return "*.*.*.*"; + } + return value.replaceAll(".", "*"); + } + +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeExtractorUtils.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeExtractorUtils.java new file mode 100644 index 000000000..e78d782fa --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeExtractorUtils.java @@ -0,0 +1,69 @@ +package run.mone.z.desensitization.service.common; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.Stack; + +/** + * @author wmin + * @date 2023/6/7 + */ +@Slf4j +public class CodeExtractorUtils { + + /** + * 只能处理单段代码 + * 代码提取,返回代码片段开始和结束的index + */ + public static Pair codeExtractor(String str) { + Stack stack = new Stack<>(); + char[] arr = str.toCharArray(); + int firstBra = -1; + int lastBra = -1; + for (int i=0;i codeExtractorWithLabel(String str) { + if (str.contains(Consts.codeExtractorStartLabel) && str.contains(Consts.codeExtractorEndLabel)){ + int startIndex = str.indexOf(Consts.codeExtractorStartLabel); + int endIndex = str.indexOf(Consts.codeExtractorEndLabel, startIndex + Consts.codeExtractorStartLabel.length()); + return Pair.of(true, startIndex + Consts.codeExtractorStartLabel.length()+"-"+endIndex); + } + return Pair.of(false,"not supported"); + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeParseUtils.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeParseUtils.java new file mode 100644 index 000000000..177aa6ef7 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/CodeParseUtils.java @@ -0,0 +1,69 @@ +package run.mone.z.desensitization.service.common; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParseResult; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.PackageDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import run.mone.z.desensitization.api.common.CodeTypeEnum; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** + * @author wmin + * @date 2023/6/5 + * 代码解析 + */ +@Slf4j +public class CodeParseUtils { + + public static Pair codeParse(String sourceCode){ + Pair rst = null; + try { + if (isClass(sourceCode)){ + JavaParser javaParser = new JavaParser(); + CompilationUnit compilationUnit = javaParser.parse(sourceCode).getResult().get(); + String className = compilationUnit.getType(0).getName().getIdentifier(); + if (compilationUnit.getPackageDeclaration().isPresent()){ + PackageDeclaration packageDeclaration = compilationUnit.getPackageDeclaration().get(); + className = packageDeclaration.getName()+"."+className; + } + rst = Pair.of(CodeTypeEnum.CLASS.getType(), className); + } else if (isMethod(sourceCode)){ + rst = methodCodeParse(sourceCode); + } + } catch (Exception e){ + log.error("codeParse error", e); + } + log.info("codeParse end.rst:{}", rst); + return rst; + } + + public static boolean isClass(String sourceCode){ + Pattern pattern = Pattern.compile(".*(public|protected|private)\\s+(class|interface)\\s.*", Pattern.DOTALL); + Matcher matcher = pattern.matcher(sourceCode); + return matcher.matches(); + } + + public static boolean isMethod(String sourceCode){ + String regex = "\\s*(public|protected|private)?\\s+(static\\s+)?[\\w\\<\\>\\[\\]]+\\s+[\\w\\$]+\\(.*\\)\\s*\\{.*"; + Pattern pattern = Pattern.compile(regex, Pattern.DOTALL); + Matcher matcher = pattern.matcher(sourceCode); + return matcher.matches(); + } + + public static Pair methodCodeParse(String sourceCode){ + Pair rst = null; + JavaParser javaParser = new JavaParser(); + ParseResult cu = javaParser.parseMethodDeclaration(sourceCode); + if (cu.isSuccessful()){ + rst = Pair.of(CodeTypeEnum.METHOD.getType(), Consts.tmpClassName); + } + return rst; + } + +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/Consts.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/Consts.java new file mode 100644 index 000000000..f89ad52e6 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/Consts.java @@ -0,0 +1,20 @@ +package run.mone.z.desensitization.service.common; + +/** + * @author wmin + * @date 2023/6/6 + */ +public class Consts { + + public static String tmpClassName = "TmpClassName"; + public static String tmpClassNamePrefix = "public class TmpClassName {"; + public static String tmpClassNameSuffix = "}"; + + public static String codeExtractorStartLabel = "z_desensitization_start"; + public static String codeExtractorEndLabel = "z_desensitization_end"; + + public static final String LANG_JAVA = "java"; + + public static final String LANG_GO = "go"; + +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/HttpClientUtil.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/HttpClientUtil.java new file mode 100644 index 000000000..6b53ce534 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/HttpClientUtil.java @@ -0,0 +1,138 @@ +package run.mone.z.desensitization.service.common; + +import com.alibaba.nacos.common.utils.MapUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.LaxRedirectStrategy; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.URI; +import java.util.Map; + +/** + * @author HawickMason@xiaomi.com + * @date 1/31/24 8:15 PM + */ +public class HttpClientUtil { + private static Logger log = LoggerFactory.getLogger(HttpClientUtil.class); + + private static final String APPLICATION_JSON = "application/json"; + + private static final String PREFIX = "Bearer "; + + private static final String UTF_8 = "UTF-8"; + + private static CloseableHttpClient httpClient = null; + private static RequestConfig requestConfig = null; + + static { + // 设置配置请求参数 + requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间 + .setConnectionRequestTimeout(35000)// 请求超时时间 + .setSocketTimeout(60000)// 数据读取超时时间 + .build(); + + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); + connectionManager.setMaxTotal(200); + connectionManager.setDefaultMaxPerRoute(20); + //connectionManager.setValidateAfterInactivity(TimeValue.ofMinutes(5)); + httpClient = HttpClients.custom() + .setConnectionManager(connectionManager) + .setDefaultRequestConfig(requestConfig) + .setRedirectStrategy(new LaxRedirectStrategy()) // Follow Redirect 跟随重定向 + .build(); + } + + public static String doGet(String url) { + return doGet(url, null, null, null); + } + + public static String doGet(String url, Map param) { + return doGet(url, param, null, null); + } + + public static String doGet(String url, Map param, Map headerParamMap, Pair headerTokenPair) { + String result = ""; + CloseableHttpResponse response = null; + try { + // 创建 uri + URIBuilder builder = new URIBuilder(url); + if (MapUtils.isNotEmpty(param)) { + for (String key : param.keySet()) { + builder.addParameter(key, String.valueOf(param.get(key))); + } + } + URI uri = builder.build(); + + // 创建 http GET请求 + HttpGet httpGet = new HttpGet(uri); + + if (headerTokenPair != null) { + httpGet.addHeader(headerTokenPair.getKey(), PREFIX + headerTokenPair.getValue()); + } + + if (null != headerParamMap && !headerParamMap.isEmpty()) { + for (String key : headerParamMap.keySet()) { + if (!httpGet.containsHeader(key)) { + httpGet.addHeader(key, (String) headerParamMap.get(key)); + } + } + } + // 执行请求 + response = httpClient.execute(httpGet); + // 判断返回状态是否为200 + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + result = EntityUtils.toString(response.getEntity(), UTF_8); + } else { + log.error("doGet error, response:{}", response); + } + } catch (Exception e) { + log.error("doGet error, url:{}", url, e); + } finally { + try { + if (response != null) { + response.close(); + } + } catch (IOException e) { + log.error("doGet close response error:", e); + } + } + return result; + } + + public static String doPostString(String url, String body, Map headerParamMap) { + try { + HttpPost post = new HttpPost(url); + if (headerParamMap != null && !headerParamMap.isEmpty()) { + for (String key : headerParamMap.keySet()) { + if (!post.containsHeader(key)) { + post.addHeader(key, (String) headerParamMap.get(key)); + } + } + } + post.setEntity(new StringEntity(body, UTF_8)); + CloseableHttpResponse response = httpClient.execute(post); + HttpEntity resEntity = response.getEntity(); + if (resEntity == null) { + return null; + } + return EntityUtils.toString(resEntity); + } catch (Exception e) { + log.error("error in post request,error message={}", e); + } + return null; + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/NewCodeDesensitizeUtils.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/NewCodeDesensitizeUtils.java new file mode 100644 index 000000000..8966a8867 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/NewCodeDesensitizeUtils.java @@ -0,0 +1,335 @@ +package run.mone.z.desensitization.service.common; + +import com.alibaba.nacos.common.utils.MapUtils; +import com.google.common.collect.Sets; +import com.sun.source.tree.*; +import com.sun.source.util.TreeScanner; +import com.sun.tools.javac.file.JavacFileManager; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.util.Context; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.springframework.util.CollectionUtils; +import run.mone.antlr.golang.Field; +import run.mone.antlr.golang.GoCode; +import run.mone.antlr.golang.ParseResult; +import run.mone.z.desensitization.api.bo.DesensitizeReq; +import run.mone.z.desensitization.api.bo.SensitiveWordConfigBo; +import run.mone.z.desensitization.api.common.CodeTypeEnum; +import run.mone.z.desensitization.api.common.SensitiveWordTypeEnum; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static run.mone.z.desensitization.service.common.Consts.*; + +/** + * @author wmin + * @date 2023/6/5 + * 可根据指定的敏感词进行代码脱敏 + */ +@Slf4j +public class NewCodeDesensitizeUtils { + + /** + * 敏感词key + */ + private static Set filedOrMethodNames = Sets.newHashSet("password", "pwd", "secret", "token", "ip", "host"); + + private static Set ipKeys = Sets.newHashSet( "ip", "host"); + /** + * IP白名单 + */ + private static Set ipWhite = Sets.newHashSet("127.0.0.1", "0.0.0.0"); + + private static TreeScanner scanner; + + public static String codeDesensitizeForClass(String sourceCode, String className, List sensitiveWordConfigs) throws Exception { + CompilationUnitTree compilationUnit = ClassUtils.getUnitTreeWithClassName(sourceCode, className); + TreeScanner scanner = getTreeScanner(sensitiveWordConfigs); + scanner.scan(compilationUnit, null); + String codeAfterDesensitized = compilationUnit.toString(); + if (tmpClassName.equals(className)){ + codeAfterDesensitized = codeAfterDesensitized.substring(tmpClassNamePrefix.length()+1, codeAfterDesensitized.length()-1).replaceAll("^\\n+|\\n+$", ""); + } + log.info("codeAfterDesensitized ======{}======", codeAfterDesensitized); + return codeAfterDesensitized; + } + + public static String codeDesensitizeForClass(DesensitizeReq req) throws Exception { + String sourceCode = req.getText(); + Pair rst = CodeParseUtils.codeParse(sourceCode); + if (rst!=null){ + if (CodeTypeEnum.CLASS.getType().equals(rst.getKey())){ + return codeDesensitizeForClass(sourceCode, rst.getValue(), req.getSensitiveWordConfigBo()); + } + if (CodeTypeEnum.METHOD.getType().equals(rst.getKey())){ + return codeDesensitizeForClass(tmpClassNamePrefix + sourceCode + tmpClassNameSuffix, rst.getValue(), req.getSensitiveWordConfigBo()); + } + } + return ""; + } + + private static synchronized TreeScanner getTreeScanner(List sensitiveWordConfigs){ + if (scanner!=null){ + return scanner; + } + final List sensitiveWordConfigList = CollectionUtils.isEmpty(sensitiveWordConfigs)?new ArrayList<>():sensitiveWordConfigs; + Context context = new Context(); + JavacFileManager.preRegister(context); + TreeMaker treeMaker = TreeMaker.instance(context); + scanner = new TreeScanner() { + List keys = getConfiguredSensitiveKeys(sensitiveWordConfigList); + List values = getConfiguredSensitiveValues(sensitiveWordConfigList); + @Override + public Void visitVariable(VariableTree variableTree, Void aVoid) { + String key = variableTree.getName().toString(); + + //已初始化 + if (variableTree.getInitializer()!=null) { + ExpressionTree initializer = variableTree.getInitializer(); + if (initializer instanceof LiteralTree) { + String value = ((LiteralTree) initializer).getValue().toString(); + String valueDesensitized = value; + if (isSensitiveKey(key, keys)){ + valueDesensitized = maskValue(value, ipKeys.contains(key.toLowerCase())?"ip":"content"); + } + Pair valuePair = isSensitiveValue(value, values); + if (valuePair.getKey()){ + valueDesensitized = valuePair.getValue(); + } + JCTree.JCLiteral newLiteral = treeMaker.Literal(valueDesensitized); + ((JCTree.JCVariableDecl) variableTree).init = newLiteral; + } + } + return super.visitVariable(variableTree, aVoid); + } + + @Override + public Void visitMethod(MethodTree methodTreeTree, Void aVoid) { + BlockTree body = methodTreeTree.getBody(); + if (null != body) { + List stats = body.getStatements(); + stats.forEach(it -> { + if (it instanceof JCTree.JCExpressionStatement) { + JCTree.JCExpressionStatement statement = (JCTree.JCExpressionStatement) it; + JCTree.JCExpression expression = statement.getExpression(); + if (expression instanceof JCTree.JCMethodInvocation) { + JCTree.JCMethodInvocation invocation = (JCTree.JCMethodInvocation) expression; + com.sun.tools.javac.util.List arguments = invocation.getArguments(); + if (arguments.head!=null){ + com.sun.tools.javac.util.List newArguments = null; + for (int i =0;i pair = isSensitiveValue(value, values); + if (pair.getKey()){ + arg = treeMaker.Literal(pair.getValue()); + } + if (newArguments==null){ + newArguments = com.sun.tools.javac.util.List.of(arg); + } else { + newArguments = newArguments.append(arg); + } + } + if (arg instanceof JCTree.JCIdent) { + if (newArguments==null){ + newArguments = com.sun.tools.javac.util.List.of(arg); + } else { + newArguments = newArguments.append(arg); + } + } + } + invocation.args = newArguments; + } + } + } + }); + } + return super.visitMethod(methodTreeTree, aVoid); + } + }; + return scanner; + } + + + private static boolean isSensitiveKey(String key, List sensitiveWordConfigs){ + //todo 只要包含就算,可能误判 + ZNormalizer.normailize(key); + if (CollectionUtils.isEmpty(sensitiveWordConfigs)){ + for (String keyword : filedOrMethodNames) { + if (key.toLowerCase().contains(keyword.toLowerCase())) { + return true; + } + } + } + for (SensitiveWordConfigBo config : sensitiveWordConfigs){ + if (config.getRegexMatch()){ + Pattern pattern = Pattern.compile(config.getContent()); + if (pattern.matcher(key).matches()){ + return true; + } + } else if (config.getCaseSensitive()){ + if (key.contains(config.getContent())) { + return true; + } + } else { + if (key.toLowerCase().contains(config.getContent().toLowerCase())) { + return true; + } + } + } + return checkSensitivityFromZ(key); + } + + private static boolean checkSensitivityFromZ(String key) { + // TODO 从z获取敏感词信息 + return false; + } + + private static Pair isSensitiveValue(String value, List sensitiveWordConfigs){ + if (CollectionUtils.isEmpty(sensitiveWordConfigs)){ + Pair ipRst = hasSensitiveIP(value); + if (ipRst.getKey()){ + return ipRst; + } + Pair pwdRst = hasSensitivePwd(value); + return pwdRst; + } + for (SensitiveWordConfigBo config : sensitiveWordConfigs){ + if (config.getRegexMatch()){ + Pattern pattern = Pattern.compile(config.getContent()); + if (pattern.matcher(value).matches()){ + return Pair.of(true, maskValue(value, "")); + } + } else if (config.getCaseSensitive()){ + if (value.contains(config.getContent())) { + return Pair.of(true, maskValue(value, "")); + } + } else { + if (value.toLowerCase().contains(config.getContent().toLowerCase())) { + return Pair.of(true, maskValue(value, "")); + } + } + } + return Pair.of(false, value); + } + + private static Pair hasSensitivePwd(String value){ + if (value.length() < 8) { + return Pair.of(false, value); + } + String specialCharacters = "!@#$%^&*()_-"; + boolean hasLetter = false; + boolean hasDigit = false; + boolean hasSpecialChar = false; + + for (char c : value.toCharArray()) { + if (Character.isLetter(c)) { + hasLetter = true; + } else if (Character.isDigit(c)) { + hasDigit = true; + } else { + if (specialCharacters.contains(String.valueOf(c))) { + hasSpecialChar = true; + } + } + } + //同时包含字母/数字/特殊字符 + if (hasLetter && hasDigit && hasSpecialChar){ + return Pair.of(true, maskValue(value, "value")); + } + + return Pair.of(false, value); + } + + private static Pair hasSensitiveIP(String value){ + String ipPattern = "^((\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])\\.){3}(\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])$"; + if (!ipWhite.contains(value) && Pattern.matches(ipPattern, value)){ + return Pair.of(true, maskValue(value, "ip")); + } + return Pair.of(false, value); + } + + //对敏感信息进行脱敏 + private static String maskValue(String value, String type) { + if ("ip".equals(type)){ + if (ipWhite.contains(value)){ + return value; + } + return "*.*.*.*"; + } + return value.replaceAll(".", "*"); + } + + public static String codeDesensitizeForGo(DesensitizeReq req) { + String sourceCode = req.getText(); + try { + ParseResult parsedSource = GoCode.parse(sourceCode); + sourceCode = doDesensitize(sourceCode, parsedSource, req.getSensitiveWordConfigBo()); + } catch (Exception e) { + log.error("Error while try to parse and desensitize go code, req:{}, nested exception is:", req, e); + } + return sourceCode; + } + + public static String doDesensitize(String sourceCode, ParseResult parsedSource, List sensitiveWordConfigBo) { + List fieldList = parsedSource.getFieldList(); + for (Field f : fieldList) { + // TODO: 当前处理方式将非method调用的语法元素统一处理 + if (!"method".equals(f.getType()) && isSensitiveKey(f.getK().toLowerCase(), getConfiguredSensitiveKeys(sensitiveWordConfigBo))) { + String v = f.getV(); + int lengthOfAsterisk = v.length(); // 设定 "*" 的长度 + // 使用正则表达式替换所有的模式串为 "*" + // TODO:当前为全文替换,后续可改为精准替换 + sourceCode = sourceCode.replaceAll(v, StringUtils.repeat("*", lengthOfAsterisk)); + } else { + Map> methodMap = parsedSource.getMethodMap(); + if (MapUtils.isNotEmpty(methodMap)) { + List callParams = methodMap.get(f.getK()); + List markIndex = new ArrayList<>(); + if (!CollectionUtils.isEmpty(callParams)) { + for (int i = 0; i < callParams.size(); i++) { + if (isSensitiveKey(callParams.get(i), sensitiveWordConfigBo)) { + markIndex.add(i); + } + } + } + if (!CollectionUtils.isEmpty(markIndex)) { + String v = f.getV(); + String[] callHolders = v.split(","); + if (callHolders != null && callHolders.length > 0) { + for (int index : markIndex) { + String callHolder = callHolders[index]; + int lengthOfAsterisk = callHolder.length(); + sourceCode = sourceCode.replaceAll(callHolder, StringUtils.repeat("*", lengthOfAsterisk)); + } + } + } + } + } + } + return sourceCode; + } + + private static List getConfiguredSensitiveKeys(List sensitiveWordConfigList) { + return sensitiveWordConfigList.stream().filter(i -> + null!=i && (SensitiveWordTypeEnum.All.code==i.getType() || SensitiveWordTypeEnum.FiledKey.code==i.getType()) + ).collect(Collectors.toList()); + } + + private static List getConfiguredSensitiveValues(List sensitiveWordConfigList) { + return sensitiveWordConfigList.stream().filter(i -> + null!=i && (SensitiveWordTypeEnum.All.code==i.getType() || SensitiveWordTypeEnum.FiledValue.code==i.getType()) + ).collect(Collectors.toList()); + } + +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/ZNormalizer.java b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/ZNormalizer.java new file mode 100644 index 000000000..c0ed29541 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/main/java/run/mone/z/desensitization/service/common/ZNormalizer.java @@ -0,0 +1,25 @@ +package run.mone.z.desensitization.service.common; + +/** + * @author HawickMason@xiaomi.com + * @date 1/31/24 2:32 PM + */ +public class ZNormalizer { + + public static String normailize(String word) { + // remove all nonsense char + removeNonLetters(word); + // to lower case + return word.toLowerCase(); + } + + public static String removeNonLetters(String input) { + StringBuilder result = new StringBuilder(); + for (char c : input.toCharArray()) { + if (Character.isLetter(c)) { + result.append(c); + } + } + return result.toString(); + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/GoCodeTest.java b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/GoCodeTest.java new file mode 100644 index 000000000..bbab502df --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/GoCodeTest.java @@ -0,0 +1,87 @@ +package run.mone.z.desensitization.app.test; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.junit.jupiter.api.Test; +import run.mone.antlr.golang.GoCode; +import run.mone.antlr.golang.ParseResult; +import run.mone.z.desensitization.api.bo.SensitiveWordConfigBo; +import run.mone.z.desensitization.service.common.NewCodeDesensitizeUtils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2024/2/1 22:50 + */ +public class GoCodeTest { + + + @Test + public void testParse() { + try { + String config = "[\n" + + "\t\t{\n" + + "\t\t\t\"type\": 1,\n" + + "\t\t\t\"content\": \"(?i)(sessiontoken|session|token|jwt)\",\n" + + "\t\t\t\"isRegexMatch\": true,\n" + + "\t\t\t\"isCaseSensitive\": false\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"type\": 1,\n" + + "\t\t\t\"content\": \"(?i)(username|user|admin)\",\n" + + "\t\t\t\"isRegexMatch\": true,\n" + + "\t\t\t\"isCaseSensitive\": false\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"type\": 2,\n" + + "\t\t\t\"content\": \"^\\\\d{17}(\\\\d|X)$\",\n" + + "\t\t\t\"isRegexMatch\": true,\n" + + "\t\t\t\"isCaseSensitive\": false\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"type\": 1,\n" + + "\t\t\t\"content\": \"(?i)(jdbcurl|url|dbconnection|dbconnectionstr|dbconnectionstring)\",\n" + + "\t\t\t\"isRegexMatch\": true,\n" + + "\t\t\t\"isCaseSensitive\": false\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"type\": 1,\n" + + "\t\t\t\"content\": \"(?i)(ak|sk|accesskey|secretkey)\",\n" + + "\t\t\t\"isRegexMatch\": true,\n" + + "\t\t\t\"isCaseSensitive\": false\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"type\": 2,\n" + + "\t\t\t\"content\": \"^jdbc:(\\\\w+)\\\\:\\\\/\\\\/(\\\\w+)(:\\\\d+)?\\\\/([\\\\w\\\\.-]+)$\",\n" + + "\t\t\t\"isRegexMatch\": true,\n" + + "\t\t\t\"isCaseSensitive\": false\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"type\": 2,\n" + + "\t\t\t\"content\": \"^((2(5[0-5]|[0-4]\\\\d))|[0-1]?\\\\d{1,2})(\\\\.((2(5[0-5]|[0-4]\\\\d))|[0-1]?\\\\d{1,2})){3}$\",\n" + + "\t\t\t\"isRegexMatch\": true,\n" + + "\t\t\t\"isCaseSensitive\": false\n" + + "\t\t},\n" + + "\t\t{\n" + + "\t\t\t\"type\": 1,\n" + + "\t\t\t\"content\": \"(?i)(ip|host|pwd|password|secret|token|credentials|idCard|identityCard|)\",\n" + + "\t\t\t\"isRegexMatch\": true,\n" + + "\t\t\t\"isCaseSensitive\": false\n" + + "\t\t}\n" + + "\t]"; + String source = new String(Files.readAllBytes(Paths.get("/home/mason/Documents/Workspaces/xiaomi/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/test.go"))); + ParseResult parseResult = GoCode.parse(source); + String res = NewCodeDesensitizeUtils.doDesensitize(source, parseResult, new Gson().fromJson(config, new TypeToken>() {}.getType())); + System.out.println("Original:" + source); + System.out.println(" \n --------------------------------------------------------------------------------------------------- \n"); + System.out.println("Processed:" + res); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/JavaCodeTest.java b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/JavaCodeTest.java new file mode 100644 index 000000000..a0ad61e54 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/JavaCodeTest.java @@ -0,0 +1,96 @@ +package run.mone.z.desensitization.app.test; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import org.junit.jupiter.api.Test; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author goodjava@qq.com + * @date 2024/2/2 11:28 + */ +public class JavaCodeTest { + + @Test + public void test1() { + try { + String code = "abc public class A { int a=1; int b =2;} def"; + JavaParser javaParser = new JavaParser(); + CompilationUnit compilationUnit = javaParser.parse(code).getResult().get(); + + // 遍历所有的类型声明(包括类和接口) + for (ClassOrInterfaceDeclaration type : compilationUnit.findAll(ClassOrInterfaceDeclaration.class)) { + if (type.isPublic() && !type.isInterface()) { // 检查是否为公共类 + System.out.println("Found class: " + type.getName()); + } + } + } catch (Throwable ex) { + ex.printStackTrace(); + } + } + + + @Test + public void test2() { + String code = "abc public class DubboHealthServiceImpl implements DubboHealthService { @Override public Result health() { return Result.success(\"ok\"); } //计算两数之和 } def"; + + String code2 = "public class NacosService { private Map nacosNamingMap; @PostConstruct public void init() { } @Data public static class TokenResult { private String token; } @Data @Builder public static class NacosConf { private NacosNaming nacosNaming; } }"; + + String classPattern = "public\\s+class\\s+(\\w+)\\s*\\{.*?\\}"; + + Pattern pattern = Pattern.compile(classPattern, Pattern.DOTALL); + Matcher matcher = pattern.matcher(code2); + + if (matcher.find()) { + String classCode = matcher.group(0); // 获取整个类定义 + System.out.println("Extracted Java class:"); + System.out.println(classCode); + } else { + System.out.println("No Java class found in the string."); + } + } + + @Test + public void test3() { + String code = "ddd private int myMethod(String param1, int param2) { return param1.length() + param2; } kkk"; + String methodPattern = "(?:public|protected|private)?\\s+[\\w<>\\[\\]]+\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*(\\{.*?\\}|;)"; + + Pattern pattern = Pattern.compile(methodPattern, Pattern.DOTALL); + Matcher matcher = pattern.matcher(code); + + while (matcher.find()) { + String methodCode = matcher.group(0); // 获取整个方法定义 + System.out.println("Extracted Java method:"); + System.out.println(methodCode); + } + } + + @Test + public void testMultiple(){ + String code = MyTest.codeSnippet; + String classPattern = "(?:public|protected|private)?\\s+class\\s+(\\w+)\\s*\\{.*?\\}"; + + Pattern pattern = Pattern.compile(classPattern, Pattern.DOTALL); + Matcher matcher = pattern.matcher(code); + + int count = 1; + + while (matcher.find()) { + String className = matcher.group(1); // 获取类名 + String classCode = matcher.group(0); // 获取整个类定义 + int startIndex = matcher.start(); // 获取匹配块的开始索引 + int endIndex = matcher.end(); // 获取匹配块的结束索引 + + System.out.println("Extracted Java class " + count + ": " + className); + System.out.println("Start Index: " + startIndex); + System.out.println("End Index: " + endIndex); + System.out.println(classCode); + System.out.println(); + + count++; + } + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/MyTest.java b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/MyTest.java new file mode 100644 index 000000000..ca70028cf --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/MyTest.java @@ -0,0 +1,108 @@ +package run.mone.z.desensitization.app.test; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.Test; +import run.mone.z.desensitization.service.common.CodeDesensitizeUtils; +import run.mone.z.desensitization.service.common.CodeExtractorUtils; +import run.mone.z.desensitization.service.common.CodeParseUtils; + +import java.util.regex.Pattern; + +/** + * @author wmin + * @date 2023/6/5 + */ +public class MyTest { + + static String codeSnippet = "你是一名杰出的java程序员,我需要你帮我做一个分析和并判断。\n\n诉求如下:\n1.我会给你当前class的信息和一段需求描述,你帮我判断下实现这个需求时对当前项目上下文的依赖程度,\n依赖程度有:method、class、module、project,分别代表不依赖当前项目、依赖当前类、依赖当前模块、依赖当前项目.\n2.返回的结果必须是json格式,key固定位scope,value为依赖程度,如:{\"scope\":\"class\"}\n3.分析实现这个需求对当前项目上下文的依赖程度时有几条经验,供你参考:\n 3.1.请熟知Java项目常见的分module规则(层次划分、DDD等)及其依赖关系,并利用当前所处的位置进行依赖范围判断\n 3.2.如果不需要借助项目上下文就能实现的,则返回:{\"scope\":\"method\"}\n 3.3.如果依赖当前类(调用类的某些方法和常量等)和你的公共知识就能实现的,则返回{\"scope\":\"class\"}\n 3.4.如果判定依赖程度超过class级别,则需要你利用当前所处的类、模块及项目信息进行综合的推理,得出合适的依赖关系。\n4.如果需求描述里告诉了你scope,则你就严格按照我给定的scope\n 4.1.指定scope的格式有两种 (scope:method) 或者 (method)\n\n我给你两个例子供参考:\n例子1:\n当前class:\npublic class A {\n}\n\n当前module:\ndemo-service\n\n项目module列表:\ndemo-api、demo-service、demo-server\n\n需求:\n计算两数和\n\n返回:\n{\"scope\":\"method\"}\n\n例子1解释:\n需求为一个简单的sum需求,不需要依赖当前项目任何上下文就能实现。判定为不依赖\n\n例子2:\n当前class:\npublic class EmbeddingController {\n @ResponseBody\n @RequestMapping(value = \"/embedding\", method = RequestMethod.GET)\n public Result\u003cVoid\u003e embedding(String text);\n}\n\n当前module:\ndemo-server\n\n项目module列表:\ndemo-api、demo-service、demo-server\n\n需求:\n将一个上传的文件内容进行向量化处理,并存储\n\n返回:\n{\"scope\":\"project\"}\n\n例子2解释:\n分析当前class上下文可以判定出需求对本项目是有一定依赖关系的;\n分析当前类名和class信息可以判断出当前类是一个Controller,Controller一般轻逻辑,通过依赖调用来实现具体逻辑;\n分析所在module是demo-server,要实现这个需求,最有可能会调用一个demo-service模块的向量化处理service,同时还有落库Dao层操作;\n综上判断判定依赖为project\n\n\n下面我将给你一个真实的需求,请返回我json判定结果:\n\n当前所在class:\nz_desensitization_start\n@DubboService(interfaceClass = DubboHealthService.class, timeout = 1000, group = \"${dubbo.group}\", version = \"1.0\")\n@Slf4j\npublic class DubboHealthServiceImpl implements DubboHealthService {\n\n @Override\n public Result\u003cString\u003e health() {\n return Result.success(\"ok\");\n }\n \n //计算两数之和\n}\nz_desensitization_end\n当前所在module:\nz-desensitization-app\n\n项目module列表:\nz-desensitization-api,test,z-desensitization-app,z-desensitization-server,z-desensitization-domain,odin.debug,z-desensitization-infrastructure\n\n需求:\n计算两数之和"; + + static String codeSnippet2 = "public class DesensitizeReq implements Serializable {\n" + + " private String text;\n" + + " private List sensitiveWordConfigBo;\n" + + " private Boolean aiDesensitizeFlag;\n" + + " private String ip = \"1.1.1.1\";\n" + + "\n" + + " public String getText() {\n" + + " return text;\n" + + " }\n" + + "\n" + + " public void setText(String text) {\n" + + " this.text = text;\n" + + " }\n" + + "\n" + + " public List getSensitiveWordConfigBo() {\n" + + " return sensitiveWordConfigBo;\n" + + " }\n" + + "\n" + + " public void setSensitiveWordConfigBo(List sensitiveWordConfigBo) {\n" + + " this.sensitiveWordConfigBo = sensitiveWordConfigBo;\n" + + " }\n" + + "\n" + + " public Boolean getAiDesensitizeFlag() {\n" + + " return aiDesensitizeFlag;\n" + + " }\n" + + "\n" + + " public void setAiDesensitizeFlag(Boolean aiDesensitizeFlag) {\n" + + " this.aiDesensitizeFlag = aiDesensitizeFlag;\n" + + " }\n" + + "\n" + + " //计算两数之和(method)\n" + + "}"; + + @Test + public void testReg(){ + Pattern pattern = Pattern.compile("(?i)(ip|host|pwd|password|secret|token|credentials|idCard|identityCard)"); + System.out.println(pattern.matcher("IP").matches()); + System.out.println(pattern.matcher("password").matches()); + System.out.println(pattern.matcher("myHo").matches()); + System.out.println(pattern.matcher("idcard").matches()); + } + + @Test + public void testClassAfterCodeExtractor() throws Exception { + String codeSnippet1 = codeSnippet; + Pair rst = CodeExtractorUtils.codeExtractorWithLabel(codeSnippet1); + System.out.println(rst); + if (rst.getKey()){ + String[] index = rst.getValue().split("-"); + String code = codeSnippet1.substring(Integer.parseInt(index[0]), Integer.parseInt(index[1])); + System.out.println(code); + System.out.println("isClass:"+CodeParseUtils.isClass(code)); + CodeDesensitizeUtils.codeDesensitizeForClass(code); + } + } + + @Test + public void testClass2() throws Exception { + CodeDesensitizeUtils.codeDesensitizeForClass(codeSnippet2); + } + + @Test + public void testMethod() throws Exception { + String codeSnippet = "public void setActionConfMap(Map actionConfMap) {\n" + + " String password = \"12345\";\n" + + " this.actionConfMap = actionConfMap;\n" + + " }"; + //System.out.println(CodeParseUtils.isClass(codeSnippet)); + System.out.println(CodeParseUtils.isMethod(codeSnippet)); + System.out.println(CodeDesensitizeUtils.codeDesensitizeForClass(codeSnippet)); + } + + @Test + public void testCodeExtractor() throws Exception { + String codeSnippet = "testtttttt public void setActionConfMap(Map actionConfMap) {\n" + + " this.actionConfMap = actionConfMap;\n" + + " String ip = \"12.0.0.1\";\n" + + " } \n这是一些文本....."; + codeSnippet = "wwwwww wewewdsc\nwewfedscfds public static void main(String[] args) {\n String password = \"1\";\n one(password);//arg:JCIdent\n one(\"qwqw\");//arg:JCLiteral\n two(\"qwqw\", password);\n System.out.println(\"ddddeeee\");//arg:JCLiteral\n }asdsfwwwwww wewewdsc "; + Pair rst = CodeExtractorUtils.codeExtractor(codeSnippet); + if (rst.getKey()){ + String[] index = rst.getValue().split("-"); + String r = CodeDesensitizeUtils.codeDesensitizeForClass(codeSnippet.substring(Integer.parseInt(index[0]), Integer.parseInt(index[1])+1)); + StringBuilder sb = new StringBuilder(codeSnippet); + sb.replace(Integer.parseInt(index[0]), Integer.parseInt(index[1])+2, r); + System.out.println("-==-=="); + System.out.println(sb); + } + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/NewTest.java b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/NewTest.java new file mode 100644 index 000000000..27f41db8d --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/NewTest.java @@ -0,0 +1,81 @@ +package run.mone.z.desensitization.app.test; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.Test; +import run.mone.z.desensitization.api.bo.DesensitizeReq; +import run.mone.z.desensitization.api.bo.SensitiveWordConfigBo; +import run.mone.z.desensitization.service.common.CodeExtractorUtils; +import run.mone.z.desensitization.service.common.CodeParseUtils; +import run.mone.z.desensitization.service.common.NewCodeDesensitizeUtils; + +import java.util.List; + +/** + * @author wmin + * @date 2023/11/14 + */ +public class NewTest { + + String config = "[\n" + + " {\n" + + " \"id\": 10,\n" + + " \"name\": \"ip正则\",\n" + + " \"type\": 2,\n" + + " \"content\": \"^((2(5[0-5]|[0-4]\\\\d))|[0-1]?\\\\d{1,2})(\\\\.((2(5[0-5]|[0-4]\\\\d))|[0-1]?\\\\d{1,2})){3}$\",\n" + + " \"available\": true,\n" + + " \"isRegexMatch\": true,\n" + + " \"isCaseSensitive\": false,\n" + + " \"isDelete\": false,\n" + + " \"creator\": \"wangmin17\",\n" + + " \"createTime\": \"Nov 3, 2023 3:06:55 PM\",\n" + + " \"updateTime\": \"Nov 3, 2023 6:10:39 PM\"\n" + + " },\n" + + " {\n" + + " \"id\": 9,\n" + + " \"name\": \"敏感key\",\n" + + " \"type\": 1,\n" + + " \"content\": \"(?i)(ip|host|pwd|password|secret|token|credentials|idCard|identityCard|)\",\n" + + " \"available\": true,\n" + + " \"isRegexMatch\": true,\n" + + " \"isCaseSensitive\": false,\n" + + " \"isDelete\": false,\n" + + " \"creator\": \"wangmin17\",\n" + + " \"createTime\": \"Nov 3, 2023 3:05:45 PM\",\n" + + " \"updateTime\": \"Nov 14, 2023 6:38:01 PM\"\n" + + " }\n" + + "]"; + + @Test + public void testMethod() throws Exception { + String codeSnippet = "public void setActionConfMap(Map actionConfMap) {\n" + + " String password = \"12345\";\n" + + " this.actionConfMap = actionConfMap;\n" + + " }"; + //System.out.println(CodeParseUtils.isClass(codeSnippet)); + System.out.println(CodeParseUtils.isMethod(codeSnippet)); + List bos = new Gson().fromJson(config, new TypeToken>() { + }.getType()); + DesensitizeReq req = new DesensitizeReq(); + req.setText(codeSnippet); + req.setSensitiveWordConfigBo(bos); + System.out.println(NewCodeDesensitizeUtils.codeDesensitizeForClass(req)); + } + + @Test + public void testClass() throws Exception { + Pair rst = CodeExtractorUtils.codeExtractor(MyTest.codeSnippet); + if (rst.getKey()){ + String[] index = rst.getValue().split("-"); + String code = MyTest.codeSnippet.substring(Integer.parseInt(index[0]), Integer.parseInt(index[1])+1); + List bos = new Gson().fromJson(config, new TypeToken>() { + }.getType()); + DesensitizeReq req = new DesensitizeReq(); + req.setText(code); + req.setSensitiveWordConfigBo(bos); + System.out.println(CodeParseUtils.isClass(code)); + NewCodeDesensitizeUtils.codeDesensitizeForClass(req); + } + } +} diff --git a/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/test.go b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/test.go new file mode 100644 index 000000000..5eefd7d14 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/test.go @@ -0,0 +1,33 @@ +package common + +import "fmt" + +type S struct { + Password string +} + +func (s *S) SetPwd(password string) { + s.Password = password +} + +func Z(password string) { + fmt.Println(password) +} + +func SetPassord(password string) { + +} + +func A(i int, j int) { + s := S{ + Password: "abc123", + } + fmt.Println(s) + Z("z123") + Z() + fmt.Println() + SetPassord("123", "456") + +} + +var Password string = "ggogogogo" diff --git a/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/test2.go b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/test2.go new file mode 100644 index 000000000..9d7ae83ce --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-app/src/test/java/run/mone/z/desensitization/app/test/test2.go @@ -0,0 +1,3 @@ +func a() + +func b(a int, b int) \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-debug/pom.xml b/m78-all/z-desensitization/z-desensitization-debug/pom.xml new file mode 100644 index 000000000..de4c840b1 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-debug/pom.xml @@ -0,0 +1,23 @@ + + + + odin.debug + odin + 1.0.0 + 4.0.0 + + + + + com.xiaomi.mone + sautumn-server-pom + 1.0.5-0712-SNAPSHOT + + + + + + + \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-domain/pom.xml b/m78-all/z-desensitization/z-desensitization-domain/pom.xml new file mode 100644 index 000000000..bfec8fad2 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-domain/pom.xml @@ -0,0 +1,67 @@ + + + + + z-desensitization + run.mone.z + 1.0-SNAPSHOT + + 4.0.0 + + z-desensitization-domain + + + + + + org.springframework.boot + spring-boot-starter-logging + + + + + com.xiaomi.mone + sautumn-client-pom + 1.0.5-0712-SNAPSHOT + + + com.fasterxml.jackson.core + jackson-annotations + + + run.mone + infra-result + + + + + + + + z-desensitization-api + run.mone.z + 1.0-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter-test + + + org.yaml + snakeyaml + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + + \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/gateway/DemoGateway.java b/m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/gateway/DemoGateway.java new file mode 100644 index 000000000..52dd383fb --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/gateway/DemoGateway.java @@ -0,0 +1,10 @@ +package run.mone.z.desensitization.domain.gateway; + +import run.mone.z.desensitization.domain.model.DemoReqEntiry; +import run.mone.z.desensitization.domain.model.DemoResEntiry; + +public interface DemoGateway { + + DemoResEntiry demoTest(DemoReqEntiry reqEntiry); + +} diff --git a/m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/model/DemoReqEntiry.java b/m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/model/DemoReqEntiry.java new file mode 100644 index 000000000..5223d3b4d --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/model/DemoReqEntiry.java @@ -0,0 +1,10 @@ +package run.mone.z.desensitization.domain.model; + +import lombok.Data; + +@Data +public class DemoReqEntiry { + + private String test; + +} diff --git a/m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/model/DemoResEntiry.java b/m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/model/DemoResEntiry.java new file mode 100644 index 000000000..aed04bfcd --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-domain/src/main/java/run/mone/z/desensitization/domain/model/DemoResEntiry.java @@ -0,0 +1,16 @@ +package run.mone.z.desensitization.domain.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DemoResEntiry { + + private String test; + +} diff --git a/m78-all/z-desensitization/z-desensitization-infrastructure/pom.xml b/m78-all/z-desensitization/z-desensitization-infrastructure/pom.xml new file mode 100644 index 000000000..ae31cd1ed --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-infrastructure/pom.xml @@ -0,0 +1,26 @@ + + + + z-desensitization + run.mone.z + 1.0-SNAPSHOT + + 4.0.0 + + z-desensitization-infrastructure + + + + + + z-desensitization-domain + run.mone.z + 1.0-SNAPSHOT + + + + + + \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-infrastructure/src/main/java/run/mone/z/desensitization/gateway/DemoGatewayImpl.java b/m78-all/z-desensitization/z-desensitization-infrastructure/src/main/java/run/mone/z/desensitization/gateway/DemoGatewayImpl.java new file mode 100644 index 000000000..91615e39e --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-infrastructure/src/main/java/run/mone/z/desensitization/gateway/DemoGatewayImpl.java @@ -0,0 +1,22 @@ +package run.mone.z.desensitization.gateway; + +import com.xiaomi.sautumn.serverless.api.tool.Tool; +import org.springframework.stereotype.Service; +import run.mone.z.desensitization.domain.gateway.DemoGateway; +import run.mone.z.desensitization.domain.model.DemoReqEntiry; +import run.mone.z.desensitization.domain.model.DemoResEntiry; + +import javax.annotation.Resource; + +@Service +public class DemoGatewayImpl implements DemoGateway { + + @Resource + private Tool tool; + + @Override + public DemoResEntiry demoTest(DemoReqEntiry reqEntiry) { + return new DemoResEntiry(tool.getMd5(reqEntiry.getTest())); + } + +} diff --git a/m78-all/z-desensitization/z-desensitization-server/pom.xml b/m78-all/z-desensitization/z-desensitization-server/pom.xml new file mode 100644 index 000000000..20c0651e6 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/pom.xml @@ -0,0 +1,193 @@ + + + + z-desensitization + run.mone.z + 1.0-SNAPSHOT + + 4.0.0 + + z-desensitization-server + + + + + + + run.mone.z + z-desensitization-infrastructure + 1.0-SNAPSHOT + + + run.mone.z + z-desensitization-app + 1.0-SNAPSHOT + + + + + + + + + + src/main/resources + true + + + src/main/resources/META-INF + true + + app.properties + + META-INF/ + + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.4.1 + + + package + + shade + + + + + + + + + + run.mone.z:z-desensitization-api + run.mone.z:z-desensitization-domain + run.mone.z:z-desensitization-app + run.mone.z:z-desensitization-infrastructure + + + ${project.build.directory}/${project.artifactId}-${project.version}-mesh.jar + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.2.6.RELEASE + + run.mone.z.desensitization.bootstrap.ZDesensitizationBootstrap + + + + + repackage + + + + + + + org.mybatis.generator + mybatis-generator-maven-plugin + 1.3.7 + + src/main/resources/generatorConfig.xml + true + true + + + + + mysql + mysql-connector-java + 8.0.20 + + + com.itfsw + mybatis-generator-plugin + 1.3.8 + + + + + + + + + + + dev + + dev + + + true + + + + src/main/resources/config/dev.properties + + + + + + staging + + staging + + + + src/main/resources/config/staging.properties + + + + + + c3 + + c3 + + + + src/main/resources/config/c3.properties + + + + + + c4 + + c4 + + + + src/main/resources/config/c4.properties + + + + + + preview + + preview + + + + src/main/resources/config/preview.properties + + + + + + + + + \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/java/run/mone/z/desensitization/bootstrap/ZDesensitizationBootstrap.java b/m78-all/z-desensitization/z-desensitization-server/src/main/java/run/mone/z/desensitization/bootstrap/ZDesensitizationBootstrap.java new file mode 100644 index 000000000..8a3a70c6b --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/java/run/mone/z/desensitization/bootstrap/ZDesensitizationBootstrap.java @@ -0,0 +1,35 @@ +package run.mone.z.desensitization.bootstrap; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.SpringBootVersion; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.core.SpringVersion; +import run.mone.sautumnn.springboot.starter.anno.DubboComponentScan; +import run.mone.sautumnn.springboot.starter.miapi.dubbo.annotation.EnableDubboApiDocs; +import run.mone.sautumnn.springboot.starter.miapi.http.annotation.EnableHttpApiDocs; + + +/** + * @author wm + */ +@EnableAutoConfiguration +@ComponentScan(basePackages = {"run.mone.z.desensitization", "com.xiaomi.youpin"}) +@DubboComponentScan(basePackages = {"run.mone.z.desensitization.service", "run.mone.z.desensitization"}) +@EnableHttpApiDocs +@EnableDubboApiDocs +@Slf4j +public class ZDesensitizationBootstrap { + + + public static void main(String... args) { + try { + log.info("springboot version:{} spring version:{}", SpringBootVersion.getVersion(), SpringVersion.getVersion()); + SpringApplication.run(ZDesensitizationBootstrap.class, args); + } catch (Throwable throwable) { + log.error(throwable.getMessage(), throwable); + System.exit(-1); + } + } +} \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/resources/application.properties b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/application.properties new file mode 100644 index 000000000..ade9d1cfc --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/application.properties @@ -0,0 +1,17 @@ +#server +app.name=z-desensitization-local +server.type=${server.type} +server.port=${server.port} +server.debug=true +server.connection-timeout=1000 + +spring.main.banner-mode=off +server.tomcat.max-threads=200 +# MSF sidecar enable +side.car.open=true +#remote.side.car.server.addr=localhost +remote.side.car.server.addr= +dubbo.group=${dubbo.group} + +log.path=${log.path} +http_connectTimeout=5000 \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/c3.properties b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/c3.properties new file mode 100644 index 000000000..cec4ce4b1 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/c3.properties @@ -0,0 +1,10 @@ +#server +app.name=z-desensitization +server.type=online +server.port=8085 +server.debug=true +server.connection-timeout=1000 + +dubbo.group=online + +log.path=/home/work/log \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/c4.properties b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/c4.properties new file mode 100644 index 000000000..cec4ce4b1 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/c4.properties @@ -0,0 +1,10 @@ +#server +app.name=z-desensitization +server.type=online +server.port=8085 +server.debug=true +server.connection-timeout=1000 + +dubbo.group=online + +log.path=/home/work/log \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/dev.properties b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/dev.properties new file mode 100644 index 000000000..18188083b --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/dev.properties @@ -0,0 +1,10 @@ +#server +app.name=z-desensitization +server.type=dev +server.port=8085 +server.debug=true +server.connection-timeout=1000 + +dubbo.group=dev + +log.path=/tmp \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/preview.properties b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/preview.properties new file mode 100644 index 000000000..e12673181 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/preview.properties @@ -0,0 +1,10 @@ +#server +app.name=z-desensitization +server.type=preview +server.port=8085 +server.debug=true +server.connection-timeout=1000 + +dubbo.group=preview + +log.path=/home/work/log \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/staging.properties b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/staging.properties new file mode 100644 index 000000000..37bfc6d19 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/config/staging.properties @@ -0,0 +1,10 @@ +#server +app.name=z-desensitization +server.type=staging +server.port=8085 +server.debug=true +server.connection-timeout=1000 + +dubbo.group=staging + +log.path=/home/work/log \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/resources/dubbo.properties b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/dubbo.properties new file mode 100644 index 000000000..4027dde81 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/dubbo.properties @@ -0,0 +1 @@ +dubbo.trace.log.path=/home/work/log/dubbo/z-desensitization_ diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/resources/generatorConfig.xml b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/generatorConfig.xml new file mode 100644 index 000000000..35ce2e05c --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/generatorConfig.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/resources/logback.xml b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/logback.xml new file mode 100644 index 000000000..c057717a7 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/logback.xml @@ -0,0 +1,59 @@ + + + + + + + + + ${log.path}/z-desensitization/server.log + + %d|%-5level|%X{trace_id}|%thread|%logger{40}|%msg%n + + + ${log.path}/z-desensitization/server.log.%d{yyyy-MM-dd-HH} + ${MAX_HISTORY} + + + + + 0 + 60000 + + + + + + ${log.path}/z-desensitization/error.log + + %d|%-5level|%X{trace_id}|%thread|%logger{40}|%msg%n + + + ${log.path}/z-desensitization/error.log.%d{yyyy-MM-dd-HH} + ${MAX_HISTORY} + + + ERROR + ACCEPT + DENY + + + + + + %d|%-5level|%X{trace_id}|%thread|%logger{40}|%msg%n + + + + + + + + + + + + + + + diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/resources/mapper/ZDesensitizationRecordMapper.xml b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/mapper/ZDesensitizationRecordMapper.xml new file mode 100644 index 000000000..0aae869ad --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/mapper/ZDesensitizationRecordMapper.xml @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + + + + + + + + and ${criterion.condition} + + + and ${criterion.condition} #{criterion.value} + + + and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} + + + and ${criterion.condition} + + #{listItem} + + + + + + + + + + + id, gmt_create, creator, status, duration_time + + + text_before, text_after + + + + + + delete from z_desensitization_record + where id = #{id,jdbcType=BIGINT} + + + delete from z_desensitization_record + + + + + + + SELECT LAST_INSERT_ID() + + insert into z_desensitization_record (gmt_create, creator, status, + duration_time, text_before, text_after + ) + values (#{gmtCreate,jdbcType=TIMESTAMP}, #{creator,jdbcType=VARCHAR}, #{status,jdbcType=INTEGER}, + #{durationTime,jdbcType=BIGINT}, #{textBefore,jdbcType=LONGVARCHAR}, #{textAfter,jdbcType=LONGVARCHAR} + ) + + + + SELECT LAST_INSERT_ID() + + insert into z_desensitization_record + + + gmt_create, + + + creator, + + + status, + + + duration_time, + + + text_before, + + + text_after, + + + + + #{gmtCreate,jdbcType=TIMESTAMP}, + + + #{creator,jdbcType=VARCHAR}, + + + #{status,jdbcType=INTEGER}, + + + #{durationTime,jdbcType=BIGINT}, + + + #{textBefore,jdbcType=LONGVARCHAR}, + + + #{textAfter,jdbcType=LONGVARCHAR}, + + + + + + update z_desensitization_record + + + id = #{record.id,jdbcType=BIGINT}, + + + gmt_create = #{record.gmtCreate,jdbcType=TIMESTAMP}, + + + creator = #{record.creator,jdbcType=VARCHAR}, + + + status = #{record.status,jdbcType=INTEGER}, + + + duration_time = #{record.durationTime,jdbcType=BIGINT}, + + + text_before = #{record.textBefore,jdbcType=LONGVARCHAR}, + + + text_after = #{record.textAfter,jdbcType=LONGVARCHAR}, + + + + + + + + update z_desensitization_record + set id = #{record.id,jdbcType=BIGINT}, + gmt_create = #{record.gmtCreate,jdbcType=TIMESTAMP}, + creator = #{record.creator,jdbcType=VARCHAR}, + status = #{record.status,jdbcType=INTEGER}, + duration_time = #{record.durationTime,jdbcType=BIGINT}, + text_before = #{record.textBefore,jdbcType=LONGVARCHAR}, + text_after = #{record.textAfter,jdbcType=LONGVARCHAR} + + + + + + update z_desensitization_record + set id = #{record.id,jdbcType=BIGINT}, + gmt_create = #{record.gmtCreate,jdbcType=TIMESTAMP}, + creator = #{record.creator,jdbcType=VARCHAR}, + status = #{record.status,jdbcType=INTEGER}, + duration_time = #{record.durationTime,jdbcType=BIGINT} + + + + + + update z_desensitization_record + + + gmt_create = #{gmtCreate,jdbcType=TIMESTAMP}, + + + creator = #{creator,jdbcType=VARCHAR}, + + + status = #{status,jdbcType=INTEGER}, + + + duration_time = #{durationTime,jdbcType=BIGINT}, + + + text_before = #{textBefore,jdbcType=LONGVARCHAR}, + + + text_after = #{textAfter,jdbcType=LONGVARCHAR}, + + + where id = #{id,jdbcType=BIGINT} + + + update z_desensitization_record + set gmt_create = #{gmtCreate,jdbcType=TIMESTAMP}, + creator = #{creator,jdbcType=VARCHAR}, + status = #{status,jdbcType=INTEGER}, + duration_time = #{durationTime,jdbcType=BIGINT}, + text_before = #{textBefore,jdbcType=LONGVARCHAR}, + text_after = #{textAfter,jdbcType=LONGVARCHAR} + where id = #{id,jdbcType=BIGINT} + + + update z_desensitization_record + set gmt_create = #{gmtCreate,jdbcType=TIMESTAMP}, + creator = #{creator,jdbcType=VARCHAR}, + status = #{status,jdbcType=INTEGER}, + duration_time = #{durationTime,jdbcType=BIGINT} + where id = #{id,jdbcType=BIGINT} + + + insert into z_desensitization_record + (gmt_create, creator, status, duration_time, text_before, text_after) + values + + (#{item.gmtCreate,jdbcType=TIMESTAMP}, #{item.creator,jdbcType=VARCHAR}, #{item.status,jdbcType=INTEGER}, + #{item.durationTime,jdbcType=BIGINT}, #{item.textBefore,jdbcType=LONGVARCHAR}, + #{item.textAfter,jdbcType=LONGVARCHAR}) + + + + insert into z_desensitization_record ( + + ${column.escapedColumnName} + + ) + values + + ( + + + #{item.gmtCreate,jdbcType=TIMESTAMP} + + + #{item.creator,jdbcType=VARCHAR} + + + #{item.status,jdbcType=INTEGER} + + + #{item.durationTime,jdbcType=BIGINT} + + + #{item.textBefore,jdbcType=LONGVARCHAR} + + + #{item.textAfter,jdbcType=LONGVARCHAR} + + + ) + + + \ No newline at end of file diff --git a/m78-all/z-desensitization/z-desensitization-server/src/main/resources/sql/init.sql b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/sql/init.sql new file mode 100644 index 000000000..a00b7e666 --- /dev/null +++ b/m78-all/z-desensitization/z-desensitization-server/src/main/resources/sql/init.sql @@ -0,0 +1,9 @@ +CREATE TABLE `z_desensitization_record` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `gmt_create` datetime DEFAULT NULL COMMENT '创建时间', + `creator` varchar(64) NOT NULL DEFAULT '' COMMENT '创建者', + `text_before` text NOT NULL COMMENT '原文本', + `text_after` text COMMENT '脱敏后文本', + `status` int(1) not null comment '状态, 0: 失败, 1:成功', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT='文本脱敏记录'; \ No newline at end of file From 6a6f62f7dc783e6272fdb02ebf4acb6aa45d8f25 Mon Sep 17 00:00:00 2001 From: EricDing <128116675+sadadw1@users.noreply.github.com> Date: Thu, 1 Aug 2024 19:34:09 +0800 Subject: [PATCH 13/14] feat: upgrade athena (#865) * feat: add prometheus-trace-etl release * feat: add gitlab log release jdk21 * feat: update athena * feat: update check code file path * feat: add code generator and mybatis generator --- athena-all/README.md | 59 +- athena-all/build.gradle.kts | 145 +- athena-all/dic.txt | 4586 +++++++++++++++++ athena-all/logo.svg | 5 + .../tesla}/ip/action/DynamicAction.java | 10 +- .../tesla}/ip/action/GenerateAction.java | 4 +- .../tesla/ip/action/MenuActionGroup.java | 47 + .../youpin/tesla}/ip/action/NaviAction.java | 5 +- .../youpin/tesla}/ip/action/PluginAction.java | 4 +- .../tesla}/ip/action/UltramanAction.java | 2 +- .../com/xiaomi/youpin/tesla/ip/bo/Action.java | 50 + .../youpin/tesla}/ip/bo/AddMethodConfig.java | 3 +- .../youpin/tesla}/ip/bo/AiCodePromptRes.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/AiCodeRes.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/AiMessage.java | 2 +- .../youpin/tesla}/ip/bo/AiMessageType.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/AnnoInfo.java | 2 +- .../youpin/tesla}/ip/bo/AnnoMember.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/AthenaReq.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/AudioRes.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/ClassInfo.java | 4 +- .../youpin/tesla}/ip/bo/CreateClassMeta.java | 4 +- .../youpin/tesla}/ip/bo/CreateClassRes.java | 2 +- .../youpin/tesla}/ip/bo/Dependency.java | 2 +- .../youpin/tesla}/ip/bo/ElementInfo.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/FieldInfo.java | 2 +- .../youpin/tesla}/ip/bo/GenerateCodeReq.java | 39 +- .../youpin/tesla}/ip/bo/IdeaPluginInfoBo.java | 2 +- .../youpin/tesla}/ip/bo/LombokTest.java | 2 +- .../tesla/ip/bo/M78CodeGenerationInfo.java | 71 + .../xiaomi/youpin/tesla}/ip/bo/Message.java | 2 +- .../youpin/tesla}/ip/bo/MessageConsumer.java | 2 +- .../youpin/tesla}/ip/bo/MethodInfo.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/ModelRes.java | 2 +- .../youpin/tesla}/ip/bo/ModuleInfo.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/Msg.java | 2 +- .../youpin/tesla}/ip/bo/ParamDialogReq.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/ParamInfo.java | 2 +- .../tesla}/ip/bo/PluginDeleteParam.java | 2 +- .../tesla}/ip/bo/ProjectModuleInfo.java | 2 +- .../youpin/tesla}/ip/bo/PromptContext.java | 5 +- .../youpin/tesla}/ip/bo/PromptInfo.java | 18 +- .../xiaomi/youpin/tesla}/ip/bo/ProxyAsk.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/PsiInfo.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/Req.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/Response.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/Result.java | 2 +- .../youpin/tesla}/ip/bo/RobotContext.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/RobotReq.java | 2 +- .../youpin/tesla}/ip/bo/ServerInfo.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/SpiderUrl.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/Tag.java | 8 +- .../xiaomi/youpin/tesla}/ip/bo/TbTask.java | 2 +- .../tesla}/ip/bo/TeslaPluginConfig.java | 28 +- .../xiaomi/youpin/tesla}/ip/bo/UserBo.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/UserVo.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/ValueInfo.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/ZAddrRes.java | 5 +- .../xiaomi/youpin/tesla}/ip/bo/ZAskParam.java | 2 +- .../youpin/tesla}/ip/bo/ZPromptAddonItem.java | 2 +- .../youpin/tesla}/ip/bo/ZPromptRes.java | 2 +- .../youpin/tesla}/ip/bo/ZRequestPram.java | 2 +- .../youpin/tesla}/ip/bo/chatgpt/Choice.java | 2 +- .../tesla}/ip/bo/chatgpt/Completions.java | 4 +- .../youpin/tesla}/ip/bo/chatgpt/Format.java | 2 +- .../youpin/tesla}/ip/bo/chatgpt/ImageUrl.java | 2 +- .../youpin/tesla}/ip/bo/chatgpt/LocalReq.java | 2 +- .../youpin/tesla}/ip/bo/chatgpt/Message.java | 2 +- .../tesla}/ip/bo/chatgpt/ReqContent.java | 2 +- .../tesla}/ip/bo/chatgpt/ReqMessage.java | 2 +- .../tesla}/ip/bo/chatgpt/SpeechReq.java | 2 +- .../tesla}/ip/bo/chatgpt/VisionReq.java | 2 +- .../tesla}/ip/bo/chatgpt/VisionRes.java | 2 +- .../tesla}/ip/bo/prompt/PromptParam.java | 12 +- .../tesla}/ip/bo/prompt/PromptParamType.java | 2 +- .../tesla}/ip/bo/robot/AiChatMessage.java | 2 +- .../tesla}/ip/bo/robot/AiMessageManager.java | 2 +- .../youpin/tesla}/ip/bo/robot/BoolData.java | 2 +- .../youpin/tesla}/ip/bo/robot/EventRes.java | 2 +- .../youpin/tesla}/ip/bo/robot/ItemData.java | 2 +- .../youpin/tesla}/ip/bo/robot/MapData.java | 2 +- .../tesla}/ip/bo/robot/MapDataValue.java | 2 +- .../tesla}/ip/bo/robot/MessageData.java | 2 +- .../youpin/tesla}/ip/bo/robot/MessageReq.java | 2 +- .../youpin/tesla}/ip/bo/robot/MessageRes.java | 2 +- .../tesla}/ip/bo/robot/MessageType.java | 2 +- .../ip/bo/robot/ProjectAiMessageManager.java | 2 +- .../youpin/tesla}/ip/bo/robot/Role.java | 2 +- .../tesla}/ip/bo/z/EmbeddingStatus.java | 2 +- .../youpin/tesla}/ip/bo/z/ZKnowledgeRes.java | 2 +- .../xiaomi/youpin/tesla}/ip/bo/z/ZResult.java | 2 +- .../youpin/tesla}/ip/client/MyHttpClient.java | 2 +- .../youpin/tesla}/ip/common/ApiCall.java | 14 +- .../youpin/tesla}/ip/common/ApiRes.java | 2 +- .../tesla}/ip/common/AthenaBiConsumer.java | 2 +- .../ip/common/AthenaMessageConsumer.java | 6 +- .../youpin/tesla/ip/common/Base64Utils.java | 16 + .../youpin/tesla/ip/common/ChromeUtils.java | 59 + .../youpin/tesla/ip/common/ConfigCenter.java | 71 + .../youpin/tesla}/ip/common/ConfigUtils.java | 32 +- .../xiaomi/youpin/tesla/ip/common/Const.java | 150 + .../youpin/tesla}/ip/common/Context.java | 2 +- .../tesla}/ip/common/DownloadUtils.java | 2 +- .../youpin/tesla/ip/common/ErrorMessage.java} | 15 +- .../youpin/tesla}/ip/common/Events.java | 2 +- .../youpin/tesla}/ip/common/FileUtils.java | 2 +- .../youpin/tesla}/ip/common/GlobalConfig.java | 2 +- .../tesla}/ip/common/IdeaPluginVersion.java | 2 +- .../tesla/ip/common/JavaClassUtils.java | 120 + .../youpin/tesla}/ip/common/MessageQueue.java | 5 +- .../youpin/tesla}/ip/common/Mp3Player.java | 13 +- .../youpin/tesla}/ip/common/Mp3PlayerV2.java | 2 +- .../tesla}/ip/common/NotificationCenter.java | 4 +- .../youpin/tesla}/ip/common/OggPlayer.java | 2 +- .../tesla}/ip/common/OpenImageConsumer.java | 4 +- .../tesla}/ip/common/OpenTextConsumer.java | 4 +- .../tesla}/ip/common/PluginVersion.java | 2 +- .../youpin/tesla}/ip/common/ProjectCache.java | 2 +- .../xiaomi/youpin/tesla/ip/common/Prompt.java | 267 + .../youpin/tesla}/ip/common/PromptType.java | 3 +- .../youpin/tesla}/ip/common/ProxyUtils.java | 2 +- .../xiaomi/youpin/tesla}/ip/common/Safe.java | 2 +- .../youpin/tesla/ip/common/StringUtils.java | 51 + .../tesla}/ip/common/TeslaConfigurable.java | 26 +- .../tesla}/ip/common/UltramanEvent.java | 2 +- .../tesla}/ip/common/UltramanNotifier.java | 2 +- .../youpin/tesla/ip/common/VersionUtil.java | 80 + .../tesla}/ip/component/ChatComponent.java | 5 +- .../ip/component/CreateProjectComponent.java | 4 +- .../CreateSpringBootProjectComponent.java | 5 +- .../tesla}/ip/component/FilterComponent.java | 4 +- .../tesla}/ip/component/NaviComponent.java | 5 +- .../tesla}/ip/component/PluginComponent.java | 4 +- .../ip/component/TeslaAppComponent.java | 13 +- .../tesla}/ip/component/VersionComponent.java | 4 +- .../project/AthenaProjectComment.java | 4 +- .../project/AthenaTreeSelectionListener.java | 4 +- .../tesla}/ip/consumer/CodeConsumer.java | 12 +- .../tesla}/ip/consumer/FinishConsumer.java | 6 +- .../ip/dialog/AthenaTableCellEditor.java | 22 +- .../youpin/tesla}/ip/dialog/ChromeDialog.java | 6 +- .../tesla}/ip/dialog/DialogContext.java | 2 +- .../youpin/tesla}/ip/dialog/DialogReq.java | 2 +- .../youpin/tesla}/ip/dialog/DialogResult.java | 2 +- .../tesla}/ip/dialog/DirectoryTreeDialog.java | 6 +- .../tesla/ip/dialog/MarkdownDialog.java | 203 + .../tesla}/ip/dialog/ParamTableDialog.java | 34 +- .../ip/dialog/SelectClassAndMethodDialog.java | 39 +- .../tesla}/ip/dialog/SelectModuleDialog.java | 2 +- .../youpin/tesla}/ip/dialog/bo/CellValue.java | 2 +- .../tesla}/ip/enums/InvokePromptEnums.java | 2 +- .../youpin/tesla}/ip/enums/ZTagEnums.java | 2 +- .../youpin/tesla}/ip/enums/ZTypeEnums.java | 2 +- .../youpin/tesla/ip/framework/flex/Flex.java | 72 + .../tesla}/ip/generator/ClassGenerator.java | 4 +- .../ip/generator/DirectoryGenerator.java | 4 +- .../tesla}/ip/generator/FileGenerator.java | 5 +- .../tesla}/ip/generator/PackageGenerator.java | 7 +- .../tesla}/ip/generator/PomGenerator.java | 4 +- .../listener/ChromeMessageRouterHandler.java | 271 +- .../tesla}/ip/listener/DevToolsDialog.java | 2 +- .../tesla}/ip/listener/LocalHandler.java | 8 +- .../tesla}/ip/listener/MenuHandler.java | 2 +- .../tesla}/ip/listener/OpenAiListener.java | 2 +- .../tesla/ip/listener/PromptHandler.java | 127 + .../xiaomi/youpin/tesla}/ip/listener/Req.java | 2 +- .../tesla/ip/listener/RequestHandler.java | 21 + .../ip/listener/UltrmanTreeKeyAdapter.java | 79 +- .../tesla}/ip/listener/VisionHandler.java | 80 +- .../ip/renderer/CustomIconRenderer.java | 2 +- .../AthenaSearchEverywhereContributor.java | 20 +- ...enaSearchEverywhereContributorFactory.java | 2 +- .../tesla}/ip/search/AthenaSearchInfo.java | 2 +- .../ip/search/MyChooseByNameContributor.java | 2 +- .../ip/search/MyCustomNavigationItem.java | 2 +- .../tesla}/ip/service/AbstractService.java | 4 +- .../youpin/tesla/ip/service/AiService.java | 30 + .../youpin/tesla/ip/service/BotService.java | 356 ++ .../youpin/tesla}/ip/service/ClassFinder.java | 6 +- .../tesla}/ip/service/ClipboardService.java | 2 +- .../youpin/tesla/ip/service/CodeService.java | 1774 +++++++ .../tesla/ip/service/DocumentService.java | 107 + .../tesla}/ip/service/EditorService.java | 2 +- .../youpin/tesla/ip/service/GuideService.java | 464 ++ .../tesla/ip/service/LocalAiService.java | 520 ++ .../youpin/tesla/ip/service/M78Service.java | 79 + .../tesla/ip/service/PromptService.java | 1001 ++++ .../tesla/ip/service/ProxyAiService.java | 100 + .../tesla/ip/service/PsiMethodUtils.java | 176 + .../tesla/ip/service/QuickFixInvokeUtil.java | 210 + .../tesla}/ip/service/RobotService.java | 155 +- .../tesla}/ip/service/ScriptService.java | 22 +- .../tesla}/ip/service/SpiderService.java | 16 +- .../youpin/tesla/ip/service/TaskService.java} | 38 +- .../youpin/tesla/ip/service/TextService.java | 106 + .../tesla}/ip/service/UltramanService.java | 4 +- .../ip/service/UltramanServiceImpl.java | 29 +- .../youpin/tesla}/ip/service/UserService.java | 26 +- .../youpin/tesla/ip/service/XmlService.java | 147 + .../ip/service/consumer/BotMsgConsumer.java | 107 + .../xiaomi/youpin/tesla}/ip/ui/BuildUi.form | 2 +- .../xiaomi/youpin/tesla}/ip/ui/BuildUi.java | 10 +- .../xiaomi/youpin/tesla}/ip/ui/ChatUi.form | 2 +- .../xiaomi/youpin/tesla}/ip/ui/ChatUi.java | 10 +- .../youpin/tesla}/ip/ui/CodeGeneratorUi.form | 2 +- .../youpin/tesla}/ip/ui/CodeGeneratorUi.java | 11 +- .../xiaomi/youpin/tesla}/ip/ui/ConfigUi.form | 95 +- .../xiaomi/youpin/tesla}/ip/ui/ConfigUi.java | 96 +- .../youpin/tesla}/ip/ui/CreateClassUi.form | 2 +- .../youpin/tesla}/ip/ui/CreateClassUi.java | 8 +- .../xiaomi/youpin/tesla}/ip/ui/FilterUi.form | 2 +- .../xiaomi/youpin/tesla}/ip/ui/FilterUi.java | 11 +- .../xiaomi/youpin/tesla}/ip/ui/NaviUi.form | 2 +- .../xiaomi/youpin/tesla}/ip/ui/NaviUi.java | 2 +- .../xiaomi/youpin/tesla}/ip/ui/SelectUi.form | 2 +- .../xiaomi/youpin/tesla}/ip/ui/SelectUi.java | 4 +- .../tesla}/ip/ui/SpringBootProGenerator.form | 2 +- .../tesla}/ip/ui/SpringBootProGenerator.java | 36 +- .../youpin/tesla}/ip/ui/TaskCreateUi.form | 2 +- .../youpin/tesla}/ip/ui/TaskCreateUi.java | 10 +- .../tesla}/ip/ui/UltramanConsoleUi.form | 2 +- .../tesla}/ip/ui/UltramanConsoleUi.java | 2 +- .../youpin/tesla}/ip/ui/UltramanTreeUi.form | 2 +- .../youpin/tesla}/ip/ui/UltramanTreeUi.java | 14 +- .../xiaomi/youpin/tesla}/ip/ui/VersionUi.form | 6 +- .../xiaomi/youpin/tesla}/ip/ui/VersionUi.java | 4 +- .../youpin/tesla/ip/util/ActionUtils.java | 28 + .../youpin/tesla}/ip/util/AnnoUtils.java | 6 +- .../youpin/tesla/ip/util/EditorUtils.java | 350 ++ .../youpin/tesla}/ip/util/FileUtils.java | 4 +- .../youpin/tesla/ip/util/FixCodeUtils.java | 103 + .../xiaomi/youpin/tesla/ip/util/GitUtils.java | 125 + .../youpin/tesla}/ip/util/HintUtils.java | 10 +- .../youpin/tesla/ip/util/ImportUtils.java | 161 + .../youpin/tesla}/ip/util/LabelUtils.java | 9 +- .../youpin/tesla}/ip/util/LockUtils.java | 2 +- .../youpin/tesla/ip/util/MarkDownUtils.java | 48 + .../youpin/tesla/ip/util/MarkdownFilter.java | 62 + .../xiaomi/youpin/tesla/ip/util/NetUtils.java | 154 + .../xiaomi/youpin/tesla}/ip/util/Notify.java | 4 +- .../youpin/tesla}/ip/util/PackageUtils.java | 9 +- .../youpin/tesla}/ip/util/ProjectUtils.java | 58 +- .../youpin/tesla/ip/util/PromptUtils.java | 675 +++ .../youpin/tesla/ip/util/PsiClassFixer.java | 204 + .../youpin/tesla}/ip/util/PsiClassUtils.java | 237 +- .../youpin/tesla}/ip/util/PsiFieldUtils.java | 8 +- .../youpin/tesla}/ip/util/ResourceUtils.java | 75 +- .../youpin/tesla}/ip/util/RunUntil.java | 2 +- .../xiaomi/youpin/tesla/ip/util/RunUtils.java | 52 + .../tesla}/ip/util/ScreenSizeUtils.java | 2 +- .../youpin/tesla}/ip/util/SpringUtils.java | 2 +- .../youpin/tesla/ip/util/TerminalUtils.java | 167 + .../youpin/tesla/ip/util/TestUtils.java | 87 + .../tesla}/ip/util/UltramanConsole.java | 34 +- .../youpin/tesla}/ip/util/WindowUtils.java | 2 +- .../youpin/tesla}/ip/util/XmlUtils.java | 59 +- .../window/UltramanConsoleWindowFactory.java | 4 +- .../ip/window/UltramanWindowFactory.java | 85 + .../run/mone/m78/ip/action/ActionChain.java | 57 - .../run/mone/m78/ip/action/ActionEnum.java | 16 - .../run/mone/m78/ip/action/AthenaAction.java | 65 - .../run/mone/m78/ip/action/ChatAction.java | 37 - .../run/mone/m78/ip/action/CommonAction.java | 43 - .../m78/ip/action/CreateFilterAction.java | 34 - .../m78/ip/action/CreateProjectAction.java | 37 - .../action/CreateSprintBootProjectAction.java | 37 - .../m78/ip/action/DynamicActionGroup.java | 27 - .../run/mone/m78/ip/action/MenuAction.java | 32 - .../mone/m78/ip/action/MenuActionGroup.java | 37 - .../run/mone/m78/ip/action/TestAction.java | 52 - .../run/mone/m78/ip/client/GrpcClient.java | 225 - .../run/mone/m78/ip/common/ChromeUtils.java | 39 - .../run/mone/m78/ip/common/ColorEggUtils.java | 124 - .../run/mone/m78/ip/common/ConfigCenter.java | 51 - .../java/run/mone/m78/ip/common/Const.java | 64 - .../mone/m78/ip/common/JavaClassUtils.java | 51 - .../java/run/mone/m78/ip/common/Prompt.java | 142 - .../run/mone/m78/ip/common/StringUtils.java | 21 - .../m78/ip/component/UltramanComponent.java | 46 - .../mone/m78/ip/listener/PromptHandler.java | 50 - .../mone/m78/ip/listener/RequestHandler.java | 12 - .../ip/listener/TreeMouseClickedListener.java | 102 - .../run/mone/m78/ip/service/AiService.java | 24 - .../mone/m78/ip/service/ChatGptService.java | 31 - .../run/mone/m78/ip/service/CodeService.java | 861 ---- .../mone/m78/ip/service/DocumentService.java | 52 - .../mone/m78/ip/service/LocalAiService.java | 139 - .../run/mone/m78/ip/service/MusicService.java | 116 - .../mone/m78/ip/service/PromptService.java | 356 -- .../mone/m78/ip/service/ProxyAiService.java | 41 - .../mone/m78/ip/service/PsiMethodUtils.java | 49 - .../run/mone/m78/ip/service/TestService.java | 37 - .../run/mone/m78/ip/service/TextService.java | 56 - .../run/mone/m78/ip/service/XmlService.java | 56 - .../main/java/run/mone/m78/ip/ui/TestUi.form | 80 - .../main/java/run/mone/m78/ip/ui/TestUi.java | 207 - .../java/run/mone/m78/ip/ui/UltramanUi.form | 99 - .../java/run/mone/m78/ip/ui/UltramanUi.java | 68 - .../run/mone/m78/ip/util/EditorUtils.java | 149 - .../java/run/mone/m78/ip/util/GitUtils.java | 54 - .../run/mone/m78/ip/util/ImportUtils.java | 52 - .../run/mone/m78/ip/util/PromptUtils.java | 257 - .../run/mone/m78/ip/util/TerminalUtils.java | 86 - .../java/run/mone/m78/ip/util/TestUtils.java | 52 - .../m78/ip/window/UltramanWindowFactory.java | 43 - .../mone/mone/ultraman/grpc/CommonUtils.java | 19 - .../run/mone/mone/ultraman/grpc/Service.java | 87 - .../mone/ultraman/grpc/UltramanRequest.java | 1073 ---- .../grpc/UltramanRequestOrBuilder.java | 73 - .../mone/ultraman/grpc/UltramanResponse.java | 1131 ---- .../grpc/UltramanResponseOrBuilder.java | 78 - .../ultraman/grpc/UltramanServiceGrpc.java | 401 -- .../java/run/mone/ultraman/AthenaContext.java | 28 +- .../run/mone/ultraman/AthenaInspection.java | 202 +- .../ultraman/AthenaSuggestionInspection.java | 32 +- .../java/run/mone/ultraman/DemoService.java | 31 + .../run/mone/ultraman/HttpServerHandler.java | 409 +- .../run/mone/ultraman/UltramanHttpServer.java | 60 - .../action/AthenaStatusBarAction.java | 21 + .../action/RegenerateCompletionAction.java | 46 + .../ultraman/ai/MyCompletionContributor.java | 4 +- .../ultraman/background/AiBackgroundTask.java | 44 + .../run/mone/ultraman/background/AiCode.java | 11 +- .../ultraman/background/AthenaEditorTask.java | 10 +- .../mone/ultraman/background/AthenaTask.java | 287 +- .../run/mone/ultraman/background/BotTask.java | 26 + .../ultraman/background/EditorAiCode.java | 6 +- .../run/mone/ultraman/bo/AthenaClassInfo.java | 8 + .../run/mone/ultraman/bo/DesensitizeReq.java | 25 + .../run/mone/ultraman/bo/PoClassInfo.java | 18 + .../java/run/mone/ultraman/bo/Version.java | 17 +- .../ultraman/common/ActionEventUtils.java | 114 +- .../java/run/mone/ultraman/common/Code.java | 4 +- .../run/mone/ultraman/common/CodeUtils.java | 100 +- .../ultraman/common/FunctionReqUtils.java | 4 +- .../ultraman/common/GitProjectOpener.java | 20 + .../run/mone/ultraman/common/GsonUtils.java | 25 + .../run/mone/ultraman/common/ImportCode.java | 15 +- .../run/mone/ultraman/common/SafeRun.java | 5 +- .../run/mone/ultraman/common/ScopeEnum.java | 22 + .../mone/ultraman/common/TemplateUtils.java | 5 +- .../mone/ultraman/common/TestRunnerUtils.java | 83 + .../adapter/TestRunnerProcessAdapter.java | 65 + .../mone/ultraman/event/EventListener.java | 4 +- .../AthenaMethodLineMarkerProvider.java | 94 + .../run/mone/ultraman/http/HttpClient.java | 15 +- .../java/run/mone/ultraman/http/WsClient.java | 112 + .../ultraman/http/handler/BaseHandler.java | 29 + .../http/handler/ReadCodeHandler.java | 156 + .../http/handler/WriteCodeHandler.java | 89 + .../AthenaApplicationActivationListener.java | 169 +- .../AthenaFileDocumentManagerListener.java | 3 + .../AthenaFileEditorManagerListener.java | 7 +- .../AthenaProjectManagerListener.java | 63 +- .../CaretHoverEditorFactoryListener.java | 55 + .../ultraman/listener/CaretHoverPlugin.java | 475 ++ .../listener/InlayCustomRenderer.java | 117 + .../ultraman/listener/bo/CompletionEnum.java | 74 + .../ultraman/listener/event/TaskEvent.java | 57 + .../manager/AthenaTypedActionHandler.java | 18 + .../ultraman/manager/InlayHintManager.java | 56 +- .../mone/ultraman/quickfix/M78Inspection.java | 54 + .../quickfix/MethoNameLocalQuickFix.java | 32 + .../ultraman/render/AthenaInlayRenderer.java | 3 + .../mone/ultraman/service/AgentService.java | 30 + .../mone/ultraman/service/AiCodeService.java | 41 +- .../ultraman/service/AthenaCodeService.java | 198 +- .../ultraman/service/AutoFlushBizService.java | 52 +- .../mone/ultraman/service/ModuleService.java | 84 +- .../startup/AthenaStartupActivity.java | 32 + .../run/mone/ultraman/state/AthenaEvent.java | 4 +- .../run/mone/ultraman/state/CalState.java | 2 +- .../run/mone/ultraman/state/FsmManager.java | 2 +- .../run/mone/ultraman/state/GlobalState.java | 6 +- .../ultraman/state/InitQuestionState.java | 2 +- .../state/PromptAndFunctionProcessor.java | 44 +- .../mone/ultraman/state/QuestionState.java | 10 +- .../run/mone/ultraman/state/StateReq.java | 4 +- .../ultraman/state/WaitQuestionState.java | 6 +- .../statusbar/AthenaStatusBarWidget.java | 168 +- .../AthenaStatusBarWidgetFactory.java | 3 +- .../run/mone/ultraman/statusbar/PopUpReq.java | 38 + .../run/mone/ultraman/visitor/M78Visitor.java | 153 + .../src/main/resources/META-INF/plugin.xml | 94 +- .../src/main/resources/athena.properties | 1 + athena-all/src/main/resources/icons/M-2.svg | 1 + athena-all/src/main/resources/icons/M.svg | 1 + athena-all/src/main/resources/icons/M2.svg | 5 + .../java/run/mone/ultraman/test/AiTest.java | 32 +- .../ultraman/test/AthenaCodeServiceTest.java | 80 +- .../run/mone/ultraman/test/Base64Test.java | 1 + .../java/run/mone/ultraman/test/BotTest.java | 103 + .../mone/ultraman/test/CommonUtilsTest.java | 11 - .../java/run/mone/ultraman/test/GsonTest.java | 1 - .../ultraman/test/MarkdownFilterTest.java | 45 + .../run/mone/ultraman/test/NetUtilsTest.java | 19 + .../mone/ultraman/test/ScriptServiceTest.java | 2 +- .../mone/ultraman/test/StringUtilsTest.java | 53 + .../run/mone/ultraman/test/TemplateTest.java | 25 +- .../mone/ultraman/test/VersionUtilTest.java | 43 + .../run/mone/ultraman/test/WsClientTest.java | 46 + .../run/mone/ultraman/test/XmlUtilsTest.java | 6 +- .../youpin/codecheck/test/CodeCheckTest.java | 12 +- jcommon/codegen/pom.xml | 17 +- .../run/mone/ai/codegen/CodeGenerator.java | 114 + .../run/mone/ai/codegen/FeatureGenerator.java | 1 + .../run/mone/ai/codegen/MybatisGenerator.java | 129 + .../ai/codegen/bo/FeatureGeneratType.java | 4 +- .../mone/ai/codegen/bo/FeatureGenerateBo.java | 16 +- .../mone/ai/codegen/plugin/LombokPlugin.java | 31 + .../plugin/RemoveGetSetMethodsPlugin.java | 32 + .../codegen/test/FeatureGeneratorTest.java | 49 + 412 files changed, 20012 insertions(+), 8492 deletions(-) create mode 100644 athena-all/dic.txt create mode 100644 athena-all/logo.svg rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/action/DynamicAction.java (82%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/action/GenerateAction.java (96%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/MenuActionGroup.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/action/NaviAction.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/action/PluginAction.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/action/UltramanAction.java (97%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Action.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/AddMethodConfig.java (89%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/AiCodePromptRes.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/AiCodeRes.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/AiMessage.java (91%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/AiMessageType.java (78%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/AnnoInfo.java (84%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/AnnoMember.java (83%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/AthenaReq.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/AudioRes.java (78%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ClassInfo.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/CreateClassMeta.java (63%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/CreateClassRes.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/Dependency.java (84%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ElementInfo.java (85%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/FieldInfo.java (89%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/GenerateCodeReq.java (67%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/IdeaPluginInfoBo.java (98%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/LombokTest.java (77%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/M78CodeGenerationInfo.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/Message.java (94%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/MessageConsumer.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/MethodInfo.java (94%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ModelRes.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ModuleInfo.java (93%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/Msg.java (84%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ParamDialogReq.java (85%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ParamInfo.java (89%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/PluginDeleteParam.java (98%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ProjectModuleInfo.java (85%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/PromptContext.java (85%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/PromptInfo.java (69%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ProxyAsk.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/PsiInfo.java (84%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/Req.java (87%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/Response.java (98%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/Result.java (97%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/RobotContext.java (89%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/RobotReq.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ServerInfo.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/SpiderUrl.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/Tag.java (58%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/TbTask.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/TeslaPluginConfig.java (81%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/UserBo.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/UserVo.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ValueInfo.java (83%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ZAddrRes.java (83%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ZAskParam.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ZPromptAddonItem.java (82%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ZPromptRes.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/ZRequestPram.java (94%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/chatgpt/Choice.java (75%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/chatgpt/Completions.java (87%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/chatgpt/Format.java (81%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/chatgpt/ImageUrl.java (78%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/chatgpt/LocalReq.java (83%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/chatgpt/Message.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/chatgpt/ReqContent.java (84%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/chatgpt/ReqMessage.java (85%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/chatgpt/SpeechReq.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/chatgpt/VisionReq.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/chatgpt/VisionRes.java (78%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/prompt/PromptParam.java (82%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/prompt/PromptParamType.java (80%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/AiChatMessage.java (97%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/AiMessageManager.java (99%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/BoolData.java (89%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/EventRes.java (87%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/ItemData.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/MapData.java (91%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/MapDataValue.java (84%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/MessageData.java (67%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/MessageReq.java (89%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/MessageRes.java (87%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/MessageType.java (86%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/ProjectAiMessageManager.java (98%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/robot/Role.java (72%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/z/EmbeddingStatus.java (83%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/z/ZKnowledgeRes.java (87%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/bo/z/ZResult.java (82%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/client/MyHttpClient.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/ApiCall.java (80%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/ApiRes.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/AthenaBiConsumer.java (87%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/AthenaMessageConsumer.java (86%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Base64Utils.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ChromeUtils.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ConfigCenter.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/ConfigUtils.java (60%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Const.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/Context.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/DownloadUtils.java (95%) rename athena-all/src/main/java/{run/mone/m78/ip/service/TaskService.java => com/xiaomi/youpin/tesla/ip/common/ErrorMessage.java} (74%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/Events.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/FileUtils.java (98%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/GlobalConfig.java (94%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/IdeaPluginVersion.java (94%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/JavaClassUtils.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/MessageQueue.java (93%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/Mp3Player.java (85%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/Mp3PlayerV2.java (97%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/NotificationCenter.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/OggPlayer.java (98%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/OpenImageConsumer.java (97%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/OpenTextConsumer.java (94%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/PluginVersion.java (94%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/ProjectCache.java (95%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Prompt.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/PromptType.java (94%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/ProxyUtils.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/Safe.java (95%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/StringUtils.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/TeslaConfigurable.java (71%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/UltramanEvent.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/common/UltramanNotifier.java (95%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/VersionUtil.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/component/ChatComponent.java (90%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/component/CreateProjectComponent.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/component/CreateSpringBootProjectComponent.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/component/FilterComponent.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/component/NaviComponent.java (89%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/component/PluginComponent.java (93%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/component/TeslaAppComponent.java (97%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/component/VersionComponent.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/component/project/AthenaProjectComment.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/component/project/AthenaTreeSelectionListener.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/consumer/CodeConsumer.java (58%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/consumer/FinishConsumer.java (77%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/dialog/AthenaTableCellEditor.java (93%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/dialog/ChromeDialog.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/dialog/DialogContext.java (81%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/dialog/DialogReq.java (90%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/dialog/DialogResult.java (89%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/dialog/DirectoryTreeDialog.java (96%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/MarkdownDialog.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/dialog/ParamTableDialog.java (87%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/dialog/SelectClassAndMethodDialog.java (87%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/dialog/SelectModuleDialog.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/dialog/bo/CellValue.java (87%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/enums/InvokePromptEnums.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/enums/ZTagEnums.java (93%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/enums/ZTypeEnums.java (96%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/framework/flex/Flex.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/generator/ClassGenerator.java (94%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/generator/DirectoryGenerator.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/generator/FileGenerator.java (91%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/generator/PackageGenerator.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/generator/PomGenerator.java (93%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/listener/ChromeMessageRouterHandler.java (57%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/listener/DevToolsDialog.java (97%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/listener/LocalHandler.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/listener/MenuHandler.java (97%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/listener/OpenAiListener.java (88%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/PromptHandler.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/listener/Req.java (89%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/RequestHandler.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/listener/UltrmanTreeKeyAdapter.java (77%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/listener/VisionHandler.java (59%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/renderer/CustomIconRenderer.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/search/AthenaSearchEverywhereContributor.java (92%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/search/AthenaSearchEverywhereContributorFactory.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/search/AthenaSearchInfo.java (89%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/search/MyChooseByNameContributor.java (98%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/search/MyCustomNavigationItem.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/service/AbstractService.java (92%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/AiService.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/BotService.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/service/ClassFinder.java (81%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/service/ClipboardService.java (94%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/CodeService.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/DocumentService.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/service/EditorService.java (85%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/GuideService.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/LocalAiService.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/M78Service.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/PromptService.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ProxyAiService.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/PsiMethodUtils.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/QuickFixInvokeUtil.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/service/RobotService.java (59%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/service/ScriptService.java (64%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/service/SpiderService.java (57%) rename athena-all/src/main/java/{run/mone/m78/ip/service/ImageService.java => com/xiaomi/youpin/tesla/ip/service/TaskService.java} (52%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/TextService.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/service/UltramanService.java (75%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/service/UltramanServiceImpl.java (52%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/service/UserService.java (54%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/XmlService.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/consumer/BotMsgConsumer.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/BuildUi.form (99%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/BuildUi.java (97%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/ChatUi.form (98%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/ChatUi.java (97%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/CodeGeneratorUi.form (99%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/CodeGeneratorUi.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/ConfigUi.form (67%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/ConfigUi.java (52%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/CreateClassUi.form (99%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/CreateClassUi.java (93%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/FilterUi.form (99%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/FilterUi.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/NaviUi.form (99%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/NaviUi.java (99%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/SelectUi.form (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/SelectUi.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/SpringBootProGenerator.form (99%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/SpringBootProGenerator.java (95%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/TaskCreateUi.form (98%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/TaskCreateUi.java (90%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/UltramanConsoleUi.form (94%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/UltramanConsoleUi.java (98%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/UltramanTreeUi.form (97%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/UltramanTreeUi.java (89%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/VersionUi.form (89%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/ui/VersionUi.java (95%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ActionUtils.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/AnnoUtils.java (91%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/EditorUtils.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/FileUtils.java (94%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/FixCodeUtils.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/GitUtils.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/HintUtils.java (86%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ImportUtils.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/LabelUtils.java (88%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/LockUtils.java (85%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/MarkDownUtils.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/MarkdownFilter.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/NetUtils.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/Notify.java (90%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/PackageUtils.java (83%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/ProjectUtils.java (74%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PromptUtils.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PsiClassFixer.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/PsiClassUtils.java (62%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/PsiFieldUtils.java (91%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/ResourceUtils.java (54%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/RunUntil.java (95%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/RunUtils.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/ScreenSizeUtils.java (96%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/SpringUtils.java (91%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/TerminalUtils.java create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/TestUtils.java rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/UltramanConsole.java (51%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/WindowUtils.java (91%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/util/XmlUtils.java (50%) rename athena-all/src/main/java/{run/mone/m78 => com/xiaomi/youpin/tesla}/ip/window/UltramanConsoleWindowFactory.java (93%) create mode 100644 athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/window/UltramanWindowFactory.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/ActionChain.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/ActionEnum.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/AthenaAction.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/ChatAction.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/CommonAction.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/CreateFilterAction.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/CreateProjectAction.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/CreateSprintBootProjectAction.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/DynamicActionGroup.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/MenuAction.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/MenuActionGroup.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/action/TestAction.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/client/GrpcClient.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/common/ChromeUtils.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/common/ColorEggUtils.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/common/ConfigCenter.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/common/Const.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/common/JavaClassUtils.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/common/Prompt.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/common/StringUtils.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/component/UltramanComponent.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/listener/PromptHandler.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/listener/RequestHandler.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/listener/TreeMouseClickedListener.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/AiService.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/ChatGptService.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/CodeService.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/DocumentService.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/LocalAiService.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/MusicService.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/PromptService.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/ProxyAiService.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/PsiMethodUtils.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/TestService.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/TextService.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/service/XmlService.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.form delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.form delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/util/EditorUtils.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/util/GitUtils.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/util/ImportUtils.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/util/PromptUtils.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/util/TerminalUtils.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/util/TestUtils.java delete mode 100644 athena-all/src/main/java/run/mone/m78/ip/window/UltramanWindowFactory.java delete mode 100644 athena-all/src/main/java/run/mone/mone/ultraman/grpc/CommonUtils.java delete mode 100644 athena-all/src/main/java/run/mone/mone/ultraman/grpc/Service.java delete mode 100644 athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequest.java delete mode 100644 athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequestOrBuilder.java delete mode 100644 athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponse.java delete mode 100644 athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponseOrBuilder.java delete mode 100644 athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanServiceGrpc.java delete mode 100644 athena-all/src/main/java/run/mone/ultraman/UltramanHttpServer.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/action/AthenaStatusBarAction.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/action/RegenerateCompletionAction.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/background/AiBackgroundTask.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/background/BotTask.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/bo/DesensitizeReq.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/bo/PoClassInfo.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/common/ScopeEnum.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/common/TestRunnerUtils.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/common/adapter/TestRunnerProcessAdapter.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/gutter/AthenaMethodLineMarkerProvider.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/http/WsClient.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/http/handler/BaseHandler.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/http/handler/ReadCodeHandler.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/http/handler/WriteCodeHandler.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/listener/CaretHoverEditorFactoryListener.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/listener/CaretHoverPlugin.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/listener/InlayCustomRenderer.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/listener/bo/CompletionEnum.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/listener/event/TaskEvent.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/quickfix/M78Inspection.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/quickfix/MethoNameLocalQuickFix.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/service/AgentService.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/startup/AthenaStartupActivity.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/statusbar/PopUpReq.java create mode 100644 athena-all/src/main/java/run/mone/ultraman/visitor/M78Visitor.java create mode 100644 athena-all/src/main/resources/athena.properties create mode 100644 athena-all/src/main/resources/icons/M-2.svg create mode 100644 athena-all/src/main/resources/icons/M.svg create mode 100644 athena-all/src/main/resources/icons/M2.svg create mode 100644 athena-all/src/test/java/run/mone/ultraman/test/BotTest.java create mode 100644 athena-all/src/test/java/run/mone/ultraman/test/MarkdownFilterTest.java create mode 100644 athena-all/src/test/java/run/mone/ultraman/test/NetUtilsTest.java create mode 100644 athena-all/src/test/java/run/mone/ultraman/test/StringUtilsTest.java create mode 100644 athena-all/src/test/java/run/mone/ultraman/test/VersionUtilTest.java create mode 100644 athena-all/src/test/java/run/mone/ultraman/test/WsClientTest.java create mode 100644 jcommon/codegen/src/main/java/run/mone/ai/codegen/CodeGenerator.java create mode 100644 jcommon/codegen/src/main/java/run/mone/ai/codegen/MybatisGenerator.java create mode 100644 jcommon/codegen/src/main/java/run/mone/ai/codegen/plugin/LombokPlugin.java create mode 100644 jcommon/codegen/src/main/java/run/mone/ai/codegen/plugin/RemoveGetSetMethodsPlugin.java create mode 100644 jcommon/codegen/src/test/java/com/xiaomi/youpin/codegen/test/FeatureGeneratorTest.java diff --git a/athena-all/README.md b/athena-all/README.md index 8c6c2713e..9bc918068 100644 --- a/athena-all/README.md +++ b/athena-all/README.md @@ -1,4 +1,31 @@ -+ jdk version:jdk17 +## startup config ++ build.gradle.kts + + 添加Maven repository ++ ResourceUtils + + ULTRAMAN_URL_PREFIX + + 修改域名为真实域名 + + Const.BOT_URL + + 修改域名为真实域名 + + Const.CONF_DASH_URL + + 修改IP为真实IP + + Const.CONF_AI_PROXY_URL + + 修改IP为真实IP + + Const.CONF_M78_URL + + 修改域名为真实域名 ++ UltramanWindowFactory + + 修改nginxChatUrl为真实url ++ WsClient + + 修改ws url为真实url ++ GuideService + + HttpClient.post修改为真实url ++ BotService + + 修改BOT_URL为真实的BOT调用的url ++ OpenImageConsumer + + imgUrl修改 ++ plugin.xml + + vendor里的url改为真实url + +## change log + 2023年12月25日 + 1.代码注释 comment_side_car + 2.代码建议 code_suggest_sidecar @@ -8,14 +35,42 @@ + 3.屏蔽一些功能+部署到外网 + 4.单元测试 + 5.查找bug + + 6.单元测试 test_code + 2023年12月26日 + 搭一个外网版本 + 2023年12月27日 + 简化ide中生成代码的流程 + 2024年01月01日 + 尽量不再使用静态方法,而是使用ioc和aop ++ 2024年01月29日 + + 优化了单元测试代码 + + 优化了引入po + 最后的版本这是效能组所有中间件+效能工具+平台的决策大脑(给用户测的) + 方法重命名 rename_method ++ 函数参数重命名 rename_method_param_name + translation 选中翻译 -+ suggest_sidecar 方法review(建议) \ No newline at end of file ++ suggest_sidecar 方法review(建议) ++ 2024年02月19日 + + 方法补全:biz_completion + + 生成代码:biz_sidecar + + 都统一叫生成代码 + + 添加的代码注释支持多语言切换 + + prompt支持了函数能力 + + 代码补全也能自动分析代码作用范围(开启代码分析) ++ 2024年02月21日 + + 优化调试模式 (用来测试的prompt:24414:test_prompt) ++ 2024年03月02日(以后很长时间内都不在做新功能了,只优化现有的4个功能 生成代码 补全代码 智能命名 单元测试) + + 解决了生成单元测试的一个bug(service里的代码在server创建测试方法的时候,不能列出老的方法) + + 如果生成局部代码的时候,所处的位置是一个注释行,则在下一行开始生成代码 + + 给参数重命名 ++ 2024年04月22日 + + 支持生成完整的测试类 test_class_code ++ 2024年06月02日 + + 所有prompt替换为bot(以后bot是第一元素) + + 代码通过Inlay生成(100294) + + 方法名重命名(rename_method->) + + 添加注释(comment_2->) + + 单元测试(test_code->) + + 生成代码(biz_sidecar->) + + 问题修复(bug_fix->) \ No newline at end of file diff --git a/athena-all/build.gradle.kts b/athena-all/build.gradle.kts index ceaf8e9ee..7d6f08527 100644 --- a/athena-all/build.gradle.kts +++ b/athena-all/build.gradle.kts @@ -1,3 +1,5 @@ +import java.util.* + plugins { id("java") id("org.jetbrains.kotlin.jvm") version "1.7.20" @@ -5,11 +7,20 @@ plugins { } group = "run.mone" -version = "2024.01.16.1" + +// Load properties from src/main/resources/athena.properties +val athenaProperties = Properties().apply { + file("src/main/resources/athena.properties").inputStream().use { load(it) } +} +// Access the property +val pluginVersion = athenaProperties.getProperty("pluginVersion") + +version = pluginVersion repositories { mavenLocal() + maven(uri("https://maven.aliyun.com/repository/public/")) mavenCentral() } @@ -19,7 +30,7 @@ repositories { intellij { version.set("2023.1.2") type.set("IC") // Target IDE Platform - plugins.set(listOf("com.intellij.java"/* Plugin Dependencies */)) + plugins.set(listOf("com.intellij.java","JUnit","org.jetbrains.plugins.terminal"/* Plugin Dependencies */)) } tasks { @@ -53,26 +64,148 @@ tasks { } dependencies { + + implementation("org.slf4j:slf4j-api:2.0.13") + implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) implementation("com.ibeetl:beetl:3.15.4.RELEASE") + implementation("org.antlr:antlr4-runtime:4.7.2") implementation("io.netty:netty-all:4.1.36.Final") implementation("com.google.code.gson:gson:2.8.9") implementation("run.mone:openai:1.4-SNAPSHOT") implementation("com.google.guava:guava:32.0.1-jre") - implementation("com.squareup.okhttp3:okhttp:4.11.0") - implementation("com.squareup.okhttp3:okhttp-sse:4.11.0") + implementation("com.squareup.okhttp3:okhttp:4.10.0") + implementation("com.squareup.okhttp3:okhttp-sse:4.10.0") implementation("org.apache.commons:commons-lang3:3.13.0") implementation("com.github.javaparser:javaparser-core:3.25.6") implementation("org.nutz:nutz:1.r.69.20210929") implementation("mysql:mysql-connector-java:8.0.28") implementation("org.apache.commons:commons-lang3:3.14.0") - + implementation("run.mone:codegen:1.5-SNAPSHOT") compileOnly("org.projectlombok:lombok:1.18.26") annotationProcessor("org.projectlombok:lombok:1.18.26") testCompileOnly("org.projectlombok:lombok:1.18.26") testAnnotationProcessor("org.projectlombok:lombok:1.18.26") -} \ No newline at end of file +} + +buildscript { + repositories { + mavenLocal() + maven(uri("https://maven.aliyun.com/repository/public/")) + mavenCentral() + } + dependencies { + classpath("com.guardsquare:proguard-gradle:7.5.0") + } +} + +tasks.register("proguard") { + verbose() +// keepdirectories()// By default, directory entries are removed. + ignorewarnings() + target("17") + + // Alternatively put your config in a separate file +// configuration("config.pro") + + // Use the jar task output as a input jar. This will automatically add the necessary task dependency. + injars(tasks.named("instrumentedJar")) +// injars("build/libs/*.jar") + +// outjars("build/${rootProject.name}-obfuscated.jar") +// injars("Athena-2024.06.03.2.jar") + outjars("build/instrumented-${rootProject.name}-obfuscated.jar") + val javaHome = System.getProperty("java.home") + // Automatically handle the Java version of this build, don't support JBR + // As of Java 9, the runtime classes are packaged in modular jmod files. +// libraryjars( +// // filters must be specified first, as a map +// mapOf("jarfilter" to "!**.jar", +// "filter" to "!module-info.class"), +// "$javaHome/jmods/java.base.jmod" +// ) + + // Add all JDK deps +// if( ! properties("skipProguard").toBoolean()) { + File("$javaHome/jmods/").listFiles()!!.forEach { libraryjars(it.absolutePath) } +// } + +// libraryjars(configurations.runtimeClasspath.get().files) +// val ideaPath = getIDEAPath() + + // Add all java plugins to classpath +// File("$ideaPath/plugins/java/lib").listFiles()!!.forEach { libraryjars(it.absolutePath) } + // Add all IDEA libs to classpath +// File("$ideaPath/lib").listFiles()!!.forEach { libraryjars(it.absolutePath) } + + libraryjars(configurations.compileClasspath.get()) + + dontshrink() + dontoptimize() + //useuniqueclassmembernames() + +// allowaccessmodification() //you probably shouldn't use this option when processing code that is to be used as a library, since classes and class members that weren't designed to be public in the API may become public + + adaptclassstrings("**.xml") + adaptresourcefilecontents("**.xml")// or adaptresourcefilecontents() + + // Allow methods with the same signature, except for the return type, + // to get the same obfuscation name. + //overloadaggressively() + // Put all obfuscated classes into the nameless root package. +// repackageclasses("") + + printmapping("build/proguard-mapping.txt") + + adaptresourcefilenames() + optimizationpasses(9) + allowaccessmodification() +// mergeinterfacesaggressively() + renamesourcefileattribute("SourceDir") + keepattributes("Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod") + + obfuscationdictionary("dic.txt") + + // 保留除指定包路径外的所有类不被混淆 + keep(""" + class !com.xiaomi.youpin.tesla.ip.common.**, + !com.xiaomi.youpin.tesla.ip.service.**, + !run.mone.ultraman.common.**, + !run.mone.ultraman.service.** { + *; + } + """.trimIndent()) + + // 允许特定包路径下的类被混淆 +// keep(""" +// class com.xiaomi.youpin.tesla.ip.common.** { *; } +// class com.xiaomi.youpin.tesla.ip.service.** { *; } +// class run.mone.ultraman.common.** { *; } +// """.trimIndent()) + +} + + +//tasks { +// prepareSandbox { +// dependsOn("proguard") +// doFirst { +// println("${rootProject.name}-${rootProject.version}") +// val original = File("build/libs/instrumented-${rootProject.name}-${rootProject.version}.jar") +// println(original.absolutePath) +// val obfuscated = File("build/instrumented-${rootProject.name}-obfuscated.jar") +// println(obfuscated.absolutePath) +// if (original.exists() && obfuscated.exists()) { +// original.delete() +// obfuscated.renameTo(original) +// println("info: plugin file obfuscated") +// } else { +// println("error: some file does not exist, plugin file not obfuscated") +// } +// } +// } +//} \ No newline at end of file diff --git a/athena-all/dic.txt b/athena-all/dic.txt new file mode 100644 index 000000000..7f3198a02 --- /dev/null +++ b/athena-all/dic.txt @@ -0,0 +1,4586 @@ +0000O000000o +000O00000Oo +000O00000o0 +000O00000o +000O00000oO +000O00000oo +000O0000O0o +000O0000OOo +000O0000Oo0 +000O0000Oo +000O0000OoO +00O0000Ooo +00O0000o00 +00O0000o0 +00O0000o0O +00O0000o0o +00O0000o +00O0000oO0 +00O0000oO +00O0000oOO +000O0000oOo +00O0000oo0 +00O0000oo +00O0000ooO +00O0000ooo +00O00oOooO +00O00oOooo +00O000O00o +00O000O0OO +00O000O0Oo +000O00oOoOo +00O000O0o0 +00O000O0o +00O000O0oO +00O000O0oo +00O000OO00 +00O000OO0o +00O000OO +00O000OOOo +00O000OOo0 +000O000OOo +00O000OOoO +00O000OOoo +00O000Oo00 +00O000Oo0 +00O000Oo0O +00O000Oo0o +00O000OoO0 +00O00O0Oo +00O000OoO +000O000OoOO +00O000OoOo +00O000Ooo0 +00O000Ooo +00O000OooO +00O000Oooo +00O000o000 +00O000o00 +00O000o00O +00O000o00o +000O000o0 +00O000o0O0 +00O000o0O +00O000o0OO +00O000o0Oo +00O000o0o0 +00O000o0o +00O000o0oo +00O000o +00O000oO00 +000O000oO0 +00O000oO0O +00O000oO0o +00O000oO +00O000oOO0 +00O000oOO +00O000oOOO +00O000oOOo +00O000oOo0 +00O000oOo +000O000oOoO +00O000oOoo +00O000oo0 +00O000oo0O +00O000oo0o +00O000oo +00O000ooO0 +00O000ooO +00O000ooOO +00O000ooOo +000O000ooo0 +00O000ooo +00O000oooO +00O000oooo +00oooOoO +00O00oOOoo +00O00O000o +00O00O00Oo +00O00O00o0 +00O00O00o +000O00O00oO +00O00O00oo +00O00O0O0o +00O00O0OO +00O00O0OOo +00O00O0Oo0 +00O00O0OoO +00O00O0Ooo +00O00O0o00 +00O00O0o0 +00O00O0o0O +0O00O0o0o +0O00O0o +0O00O0oO0 +0O00O0oOO +0O00O0oOo +0O00O0oo0 +0O00O0oo +0O00O0ooO +0O00O0ooo +00O00OO0O +0O00OO0o +0O00OOOo +0O00OOo0 +0O00OOo +0O00OOoO +0O00OOoo +0O00Oo00 +0O00Oo00o +0O00Oo0 +00O00Oo0OO +0O00Oo0Oo +0O00Oo0o0 +0O00Oo0o +0O00Oo0oO +0O00OooOO +0O00Oo0oo +0O00Oo +0O00OoO0 +0O00OoO0o +00O00OoO0O +0O00Ooo +0O00OoO +0O00OoOO0 +0O00OoOO +0O00OoOo0 +0O00OoOo +0O00OoOoO +0O00OoOoo +0O00Ooo00 +00O00Ooo0 +0O00Ooo0O +0O00Ooo0o +0O00OooO0 +0O00OooO +0O00OooOo +0O00Oooo0 +0O00Oooo +0O00Ooooo +0O00OoooO +00O00o0000 +0O00o000 +0O00o000O +0O00o000o +0O00o00 +0O00o00O0 +0O00o00O +0O00o00OO +0O00o00Oo +0O00o00o0 +00O00o00o +0O00o00oO +0O00o00oo +0O00o0 +0O00o0O00 +0O00o0O0 +0O00oo000 +0O00o0O0O +0O00o0O0o +0O00o0O +00O00o0OO0 +0O00o0OO +0O00o0OOO +0O00o0OOo +0O00o0Oo0 +0O00o0Oo +0O00o0OoO +0O00o0Ooo +0O00o0o00 +0O00o0o0 +00O00o0o0O +0O00o0o0o +0O00o0o +0O00o0oO0 +0O00o0oO +0O00o0oOO +0O00o0oOo +0O00o0oo0 +0O00o0oo +0O00o0ooO +000O00o0ooo +00O00o +00O00oO0O0 +00O00oO000 +00O00oO00 +00O00oO00O +00O00oO0OO +00O00oO00o +00O00oO0 +00O00oO0O +00O00ooO00 +0O00oO0Oo +0O00oO0o0 +0O00oO0o +0O00oO0oO +0O00oO0oo +0O00oO +0O00oOO0o +0O00oOO00 +0O00oOO0 +00O00oOO0O +0O00oOo +0O00oOO +0O00oOOO0 +0O00oOOO +0O00oOOOO +0O00oOOOo +0O00oOOo0 +0O00oOOo +0O00oOOoO +00O00oOo00 +0O00oOo0 +0O00oOo0O +0O00oOo0o +0O00oOoO +0O00oOoOO +0O00oOoo0 +0O00oOoo +0O00oo00 +0O00oo00O +00O00oo00o +0O00oo0 +0O00oo0O0 +0O00oo0O +0O00oo0OO +0O00oo0Oo +0O00oo0o0 +0O00oo0o +0O00oo0oo +0O00oo +00O00ooO0 +0O00ooO0O +0O00ooO0o +0O00ooO +0O00ooOo0 +0O00ooOO0 +0O00ooOO +0O00ooOOO +0O00ooOOo +0O00ooOo +00O00ooOoO +0O00ooOoo +0O00ooo00 +0O00ooo0 +0O00ooo0o +0O00ooo +0O00oooO0 +0O00oooO +0O00oooOO +0O00oooOo +00O00oooo0 +0O00oooo +0O00ooooo +0ooooooo +0O0O00oO +0O0O000o +0O0O00OO +0O0O00Oo +0O0O00o0 +0O0O00o +00O0O0O0o +0O0O0O +0O0O0OO0 +0O0O0OO +0O0O0OOO +0O0O0OOo +0O0O0Oo0 +0O0O0OoO +0O0O0Ooo +0O0O0o00 +00O0O0o0 +0O0O0o0O +0O0O0o0o +0O0O0o +0O0O0oO0 +0O0O0oO +0O0O0oOO +0O0O0oOo +0O0O0oo0 +0O0O0oo +000O0O0ooO +00O0O0ooo +00O0OoOo +00O0OoOO +00O0OO00O +00O0OO00o +00O0OO0O +00O0Oo0o0 +00O0OO0Oo +00O0OO0o0 +00O0OO0oO +0O0OO0oo +0O0OOO00 +0O0OOoo +0O0OOoO +0O0OOO0 +0O0OOO0O +0O0OOO0o +0OO0oO +0O0OOOO +00O0OOOOO +0O0OOOOo +0O0OOOo0 +0O0OOOo +0O0OOOoO +0O0OOOoo +0O0OOo00 +0O0OOo0O +0O0OOo0o +0O0OOo +00O0OOoO0 +0O0OOoOO +0O0OOoOo +0O0OOoo0 +0O0OOooO +0O0OOooo +0O0Oo000 +0O0Oo00 +0O0Oo00O +0O0Oo00o +00O0Oo0 +0O0Oo0O0 +0O0Oooo +0O0Oo0O +0O0Oo0OO +0O0Oo0Oo +0O0Oo0o +0O0Oo0oO +0O0Oo0oo +0o00o00O +00O0Oo +0O0OoO00 +0O0OoO0 +0O0OoO0O +0OooOO +0OoO0o +0O0OoO +0O0OoOO0 +0O0OoOOO +0O0OoOOo +00O0OoOo0 +0O0OoOoO +0O0OoOoo +0O0Ooo00 +0O0Ooo0 +0O0Ooo0O +0O0Ooo0o +0O0Ooo +0O0OooO0 +0O0OooO +00O0OooOO +0O0OooOo +0O0Oooo0 +0O0OoooO +0O0Ooooo +0O0o0000 +0O0o000 +0O0o000O +0O0o000o +0O0o00 +00O0o00O0 +0O0o00O +0O0o00OO +0O0o00Oo +0O0o00o0 +0O0o00o +0O0o00oO +0O0o00oo +0O0o0 +0O0o0O00 +00O0o0O0 +0O0o0O0O +0O0o0O0o +0O0o0O +0O0o0OO0 +0O0oo0o +0O0o0OO +0O0o0OOO +0O0o0OOo +0O0o0Oo0 +000O0o0Oo +00O0o0OoO +00O0o0Ooo +00O0o0o00 +00O0o0o0 +00O0o0o0O +00O0o0o0o +00O0o0oO0 +00O0o0oO +00O0o0oOO +00O0o0oOo +0O0o0oo +0O0o0ooO +0oOOoOO +0O0o +0O0oO000 +0O0oO00 +0O0oO0oO +0O0oO00O +0O0oO00o +00O0oO0 +0O0oO0O0 +0O0oO0O +0O0oO0OO +0O0oO0Oo +0O0oO0o0 +0O0oO0o +0O0oO0oo +0o0Oo0o0 +0O0oO +00O0oOO00 +0O0oOO0 +0o00O00O0 +0O0oOO0O +0O0oOO0o +0O0oOO +0O0oOOO0 +0O0oOOOo +0O0oOOo0 +0Oo0OOo +00O0oOOo +0O0oOOoO +0O0oOOoo +0O0oOo00 +0O0oOo0 +0ooO0Ooo +0O0oOo0O +0O0oOo0o +0O0oOo +0O0oOoO0 +00O0oOoO +0O0oOoOO +0O0oOoOo +0OOoOoo +0O0oOoo0 +0O0oOoo +0O0oOooO +0O0oOooo +0O0oo000 +0O0oo00 +00O0oo00O +0O0oo00o +0O0oo0 +0O0oo0O0 +0O0oo0O +0O0oo0OO +0O0oo0Oo +0O0oo0o0 +0O0oo0oO +0O0oo0oo +00O0oo +0O0ooO00 +0O0ooOo +0O0oooo +0O0oooO +0O0ooO0 +0O0oooOo +0O0ooO0O +0O0ooO0o +0O0ooO +00O0ooOO0 +0O0ooOO +0O0ooOOO +0O0ooOOo +0O0ooOo0 +0O0ooOoO +0O0ooOoo +0O0ooo00 +0O0ooo0 +0O0ooo0O +00O0ooo0o +0O0ooo +0O0oooO0 +0O0oooOO +0O0oooo0 +0O0ooooO +0O0ooooo +0OO0000 +0OO0000o +0OoOOO +000OO000OO +00OO000Oo +00OO000o0 +00OO000o +00OO000oO +00OO000oo +00OO00OO +00OO00O0 +00OO00O0o +00OO00O +00OO00OOO +0OO00OOo +0OO00Oo0 +0OO0ooO +0OO00Oo +0OO00OoO +0OO00Ooo +0OO00o00 +0OO00o0O +0OO00o0o +00OO00oO0 +0OO00oO +0OO00oOO +0OO00oOo +0OO00oo0 +0OO00oo +0OO00ooO +0OO00ooo +0OO0O00o +0OO0O0O +00OO0O0OO +0OO0O0Oo +0OO0O0o0 +0OO0oOo +0OO0oOO +0OO0O0o +0OO0O0oO +0OO0O0oo +0oOo00 +0OO0OO0o +00OOo00 +0OO0OO +0OO0OOO +0OO0OOOO +0OO0OOOo +0OO0OOo0 +0OO0OOo +0OO0OOoO +0OO0OOoo +0OO0Oo00 +00OO0Oo0 +0OO0Oo0O +0OO0Oo0o +0Oo0Oo0O +0OO0OoO0 +0OO0OoO +0OO0OoOO +0Oo0Ooo0 +0OO0OoOo +0OO0Ooo0 +00OO0Ooo +0OO0OooO +0OO0Oooo +0OO0o000 +0OO0o00 +0OO0o00O +0OO0o00o +0OO0o0 +0OO0o0O0 +0OO0o0OO +00OO0o0Oo +0OO0o0o0 +0OO0o0o +0OO0o0oO +0OO0o0oo +0OO0o +0OO0oO00 +0OO0oO0 +0OO0oO0O +0OO0oO0o +00OO0oOO0 +0OoOOoOo +0OO0oOOO +0OO0oOOo +0OO0oOo0 +0OO0oOoO +0OO0oOoo +0OO0oo00 +0OO0oo0 +0OO0oo0O +00OO0oo0o +0OO0oo +0OO0ooO0 +0OO0ooOO +0OO0ooOo +0OO0ooo0 +0OO0ooo +0OO0oooO +0OO0oooo +0OOO000o +000OOO00 +00OOO00O0 +00OOO00Oo +00OOO00o0 +00OOO00o +00OOO00oO +00OOO00oo +00OOO0O0O +00OOO0O0o +00OOO0O +00o00OOOOO +0OOO0OO0 +0OOO0OOO +0OOO0OOo +0OOO0Oo0 +0OOO0oO +0OOO0Oo +0OOO0OoO +0OOO0Ooo +0OOO0o00 +00OOO0o0 +0OOO0o0O +0OOO0o0o +0OOO0o +0OOO0oO0 +0OOO0oOO +0OOO0oOo +0OOO0oo0 +0OOO0oo +0OOO0ooO +00OOO0ooo +0OOO +0OOOO00O +0OOOO00o +0OOOO0 +0OOOOoO +0OOOOo0 +0OOOOoo +0OOOO0O +0OOOO0OO +00OOOO0Oo +0OOOO0o0 +0OOOO0oO +0OOOO0oo +0OOOOO00 +0OOOOO0 +0OOOOO0o +0OOOOO +0OOOOOO +0OOOOOOO +00OOOOOOo +0OOOOOo0 +0OOooOo +0OOoooo +0OOOOOo +0OOOOOoO +0OOOOOoo +0OOOOo00 +0OOOOo0O +0OOOOo0o +00OOOOo +0OOOOoO0 +0OOOOoOO +0OOOOoOo +0OOOOoo0 +0OOOOooO +0OOOOooo +0OOOo000 +0OOo000 +0OOOo00 +00OOOo00O +0OOOo00o +0OOOo0 +0ooOOo00 +0OOOo0O0 +0OOOo0O +0OOOo0OO +0OOOo0Oo +0OOOo0o0 +0OOOo0o +00OOOo0oO +0OOOo0oo +0OOOo +0OOOoO00 +0OOOoO0 +0OOOoO0O +0o0ooo0OO +0OOOoO0o +0OOOoO +0OOOoOO0 +00OOOoOO +0OOOoOOO +0OOOoOOo +0OOOoOo0 +0OOOoOo +0OOOoOoO +0OOOoOoo +0ooO00O0 +0OOOoo00 +0OOOoo0 +000o00O0oO0 +00OOOoo0O +00OOOoo0o +00OOOoo +00OOOooO0 +00OOOooO +00o0OOoOoo +00OOOooOO +00OOOooOo +00OOOooo0 +00OOOooo +0OOOoooO +0OOOoooo +0OOo0000 +0OOo000O +0OOo000o +0OOo00O0 +0OOo00O +0OOo00OO +0OOo00Oo +00OOo00o0 +0OOo00o +0OOo00oO +0OOo00oo +0ooOo +0OOo0 +0OOo0O00 +0OOo0OO +0OOo0Oo +0OOoo00 +00OOo0O0 +0OOo0O0O +0OOo0O0o +0OOoOOoO +0OOo0OO0 +0OOo0OOO +0OOo0OOo +0OOo0Oo0 +0OOo0OoO +0OOo0Ooo +00OOo0o00 +0OOo0o0 +0OOo0o0O +0OOo0o0o +0OOo0o +0OOo0oO0 +0OOo0oO +0OOo0oOO +0OOo0oOo +0OOo0oo0 +00OOo0oo +0OOo0ooO +0OOo0ooo +0OOoO000 +0OOoO00 +0OOoO00O +0OOoO00o +0OOoO0 +0OOoO0O0 +0OOoO0o +00OOoO0O +0OOoO0OO +0OOoO0Oo +0OOoO0o0 +0OOoO0oO +0OOoO0oo +0OOoO +0OOoOO00 +0OOoOO0O +0OOoOO0o +00OOoOO +0OOoOOO0 +0OOoOOO +0OOoOOOO +0OOoOOOo +0OOoOOo0 +0OOoOOo +0OOoOOoo +0OOoOo00 +0OOoOo0 +00OOoOo0O +0OOoOo0o +0OOoOo +0OOoOoO0 +0oO0OO0 +0OOoOoO +0OOoOoOO +0OOoOoOo +0OOoOoo0 +0OOoOooO +00OOoOooo +0OOoo000 +0OOoo00O +0OOoo00o +0OOoo0 +0OOoo0O0 +0OOoo0O +0OOoo0OO +0OOoo0Oo +0OOoo0o0 +000OOoo0o +00OOoo0oO +00OOoo0oo +00OOoo +00OOooO00 +00OOooO0 +00OOooO0O +00OOooO0o +00OOooO +00OOooOO0 +00OOooOO +0OOooOOO +0OOooOOo +0OOooOo0 +0OOooOoO +0OOooOoo +0OOooo00 +0OOooo0 +0OOooo0O +0OOooo0o +00OOooo +0OOoooO0 +0OOoooO +0OOoooOO +0OOoooOo +0OOoooo0 +0OOooooO +0OOooooo +0Oo00000 +0Oo0000O +00Oo0000o +0Oo000 +0Oo000O0 +0Oo000O +0Oo000OO +0Oo000Oo +0Oo000o0 +0Oo000o +0Oo000oO +0Oo000oo +00Oo00 +0Oo00O00 +0Oo00O0 +0Oo0o0Oo +0Oo00O0O +0Oo00O0o +0Oo00O +0Oo00OO0 +0Oo0o0o +0Oo00Oo +00Oo00OO +0Oo00OOO +0Oo00OOo +0Oo00Oo0 +0Oo0o0O0 +0Oo00OoO +0Oo00Ooo +0Oo00o00 +0Oo00o0 +0Oo00o0O +00Oo00o0o +0Oo00o +0Oo00oO0 +0Oo00oOO +0Oo00oo0 +0Oo00oo +0Oo00ooO +0Oo00ooo +0Oo0 +0Oo0O000 +00Oo0O00 +0Oo0O00O +0Oo0O00o +0Oo0O0 +0Oo0O0O0 +0Oo0O0O +0Oo0O0OO +0Oo0O0Oo +0Oo0O0o0 +0Oo0O0o +00Oo0O0oO +0Oo0O0oo +0o00oO00 +0o00OO00 +0Oo0O +0Oo0OO00 +0Oo0OO0 +0Oo0OO0O +0Oo0OO0o +0Oo0OO +00Oo0OOO0 +0Oo0OOOO +0Oo0OOOo +0Oo0OOo0 +0Oo0OOoO +0Oo0OOoo +0Oo0Oo00 +0Oo0Oo0 +0Oo0Oo0o +0Oo0Oo +000Oo0OoO0 +00Oo0OoO +00Oo0OoOo +00Oo0Ooo +00Oo0OooO +00Oo0Oooo +00Oo0o000 +00Oo0o00 +00Oo0o00O +00Oo0o00o +00Oo0o0 +0Oo0o0O +0Oo0o0o0 +0Oo0o0oO +0Oo0o0oo +0Oo0o +0Oo0oO00 +0Oo0ooO +0Oo0oOO +0Oo0oo0 +00Oo0ooo +0Oo0oO0 +0Oo0oO0O +0Oo0oO0o +0Oo0oO +0Oo0oOO0 +0Oo0oOOO +0Oo0oOOo +0Oo0oOo0 +0Oo0oOo +00Oo0oOoO +0Oo0oOoo +0Oo0oo00 +0Oo0oo0O +0Oo0oo0o +0Oo0oo +0Oo0ooO0 +0Oo0ooOO +0Oo0ooOo +0Oo0ooo0 +00Oo0oooO +0Oo0oooo +0Oo +0OoO0000 +0OoO000 +0OoO000O +0OoO000o +0OoO00O0 +0OoO00O +0OoO00OO +00OoO00Oo +0OoO00o0 +0OoO00o +0OoO00oO +0OoO00oo +0OoO0 +0OoO0O00 +0OoO0Oo +0OoO0O0 +0OoO0O0O +00OoO0O0o +0OoO0O +0OoO0OO0 +0OoO0OO +0OoO0OOO +0OoOo00O +0OoO0OOo +0OoO0Oo0 +0OoO0OoO +0OoO0Ooo +00OoO0o00 +0OoO0o0 +0OoO0o0O +0OoO0o0o +0OoO0oO0 +0OoO0oo +0OoO0oO +0OoO0oOO +0OoO0oOo +0OoO0oo0 +00OoO0ooO +0OoO0ooo +0OoO +0OoOO000 +0OoOOo0 +0OoOOOO +0OoOO0O +0OoOOoo +0OoOOoO +0OoOOO0 +00OoOOOo +0OoOoOo +0OoOoOO +0OoOO00 +0OoOO00O +0OoOO00o +0OoOO0 +0OoOO0O0 +0OoOO0OO +0OoOO0Oo +000OoOO0o0 +00OoOO0o +00OoOO0oO +00OoOO0oo +00OoOo +00OoOO +00OoOOO0O +00OoOOO0o +00OoOOOO0 +00OoOOOOO +00OoOOOOo +0OoOOOo0 +0OoOOOoO +0OoOOOoo +0OoOOo00 +0OoOOo0O +0OoOOo0o +0OoOOo +0OoOOoO0 +0OoOOoOO +00OoOOoo0 +0OoOOooO +0OoOOooo +0OoOo000 +0OoOooo +0OoOoo0 +0OoOo00 +0OoOo00o +0OoOo0 +0OoOo0O0 +00OoOo0o +0OoOo0O +0OoOo0OO +0OoOo0Oo +0OoOo0o0 +0OoOo0oO +0OoOo0oo +0OoOoO00 +0OoOoO0 +0OoOoO0O +00OoOoO0o +0OoOoO +0OoOoOO0 +0OoOoOOO +0OoOoOOo +0OoOoOo0 +0OoOoOoO +0OoOoOoo +0OoOoo00 +0OoOoo0O +00OoOoo0o +0OoOoo +0OoOooO0 +0OoOooO +0OoOooOO +0OoOooOo +0OoOooo0 +0OoOoooO +0OoOoooo +0Ooo0000 +00Ooo000 +0Ooo000O +0Ooo000o +0Ooo00 +0Ooo00O0 +0Ooo00O +0Ooo00OO +0Ooo00Oo +0Ooo00o0 +0Ooo00o +00Ooo00oO +0o00oo00o +0Ooo00oo +0Ooo0 +0Ooo0O00 +0Ooo0O0 +0Ooo0O0O +0Ooo0O0o +0Ooo0O +0Ooo0OO0 +00Oooo00 +0Ooo0oO +0Ooo0Oo +0Ooo0OO +0o000O0OO +0o000oO0O +0Ooo0OOO +0Ooo0OOo +0Ooo0OoO +0Ooo0Ooo +00Ooo0o00 +0Ooo0o0 +0Ooo0o0o +0Ooo0o +0Ooo0oO0 +0Ooo0oOO +0Ooo0oOo +0Ooo0oo0 +0Ooo0oo +0Ooo0ooO +00Ooo0ooo +0o0oo +0Ooo +0OooO000 +0OooO0O +0Ooooo0 +0OooooO +0OoooOO +0OoooOo +0OooO00 +0OooO00O +OooO00o +OooO0O0 +OooO0OO +OooO0Oo +OooO0o0 +OooO0o +OooO0oO +OooO0oo +OooO +0OooOO00 +OooOO0 +OooOO0O +OooOO0o +OooOOO0 +OooOOO +OooOOOO +OooOOOo +OooOOo0 +OooOOo +0OooOOoO +OooOOoo +OooOo00 +OooOo0 +OooOo0O +OooOo0o +OooOo +OooOoO0 +OooOoO +OooOoOO +0OooOoOo +OooOoo0 +OooOoo +OooOooO +OooOooo +Oooo000 +Oooo00O +Oooo00o +Oooo0 +Oooo0O0 +0Oooo0O +Oooo0OO +Oooo0o0 +Oooo0o +Oooo0oO +Oooo0oo +Oooo +OoooO00 +OoooO0 +OoooO0O +0OoooO0o +OoooO +OoooOO0 +o000oOoO +OoooOOO +OoooOOo +OoooOo0 +OoooOoO +OoooOoo +Ooooo00 +0Ooooo0O +Ooooo0o +OooooO0 +OooooOO +OooooOo +Oooooo0 +Oooooo +OoooooO +Ooooooo +o0OoOo0 +0o0OoO0O +ooOO +o00O0O +o00Oo0 +o00Ooo +o00o0O +o00ooo +oo000o +o00oO0o +o00oO0O +0o0oo000 +o0ooOO0 +o0ooOOo +o0ooOoO +o0OOO0o +o0Oo0oo +o0OO00O +oo0o0Oo +o0O0O00 +o000OOo +00oo0oOoO +0ooo0Ooo +0ooOo00O +0o0OoOO0 +0o0O00oo +0o0ooo00 +0o000OOoo +0o000OOOo +0o000OOOO +0o000OOO0 +0o0000000 +o000000 +o000000O +o000000o +o00000 +o00000O0 +o00000O +o00000OO +o00000Oo +o00000o0 +0o00000o +o0000Ooo +o00000oO +o00000oo +o0000 +o0000O00 +o0000oo +o0000oO +o0000O0 +o0000O0O +0o0000O0o +o000OO +o0000O +o0000OO0 +o0000OO +o0000OOO +o0000OOo +o0000Oo0 +o0000Oo +o0000OoO +0o0000o00 +o0000o0 +o0000o0O +o0000o0o +o0000o +o0000oO0 +o0000oOO +o0000oOo +o0000oo0 +o0000ooO +0o0000ooo +o000 +o000O000 +o000OoO +o000O0o +o000Ooo +o000O0O +o000Oo0 +o000O00 +o000O00O +0o000O00o +o000O0 +o000O0Oo +o000OO0O +o000O0O0 +o000O0o0 +o000O0oO +o000O0oo +o000O +o000OO00 +0o000OO0 +o0OoO0o +o000OO0o +o000OOO +o000OOo0 +o000OOoO +o000Oo00 +o000Oo0O +o000Oo0o +o000Oo +0o000OoO0 +o000OoOO +o000OoOo +o000Ooo0 +o000OooO +o000Oooo +o000o000 +o000o00 +o000o00O +o000o00o +0o000o0 +oooo00o +o000o0O0 +o000o0O +o000o0OO +o000o0Oo +o000o0o0 +o000o0o +o000o0oO +o000o0oo +00o000o +0o000oO00 +0o000oO0 +0o000oO0o +0o000oO +0o000oOO0 +0o000oOO +0o000oOOO +0o000oOOo +0o000oOo0 +0o000oOo +o000oOoo +o000oo00 +o000oo0 +o000oo0O +o000oo0o +o000oo +o000ooO0 +o000ooO +o000ooOO +0o000ooOo +o000ooo0 +o000ooo +o000oooO +o000oooo +o00 +o00O0000 +o0O0ooO +o00oOoo +o00O000 +0o00O000O +o00O000o +o00O00 +o00O00O +oOO00O +o00O00OO +o00O00Oo +o00O00o0 +o00O00o +o00O00oO +0o00O00oo +oo00o +o00O0 +o00O0O00 +o00O0O0 +o00O0O0O +o00O0O0o +o00O0OO0 +oo0o0O0 +o00O0OO +0o00Oo00O +o00O0OOO +o00O0OOo +o00O0Oo0 +oo0oOO0 +o00O0Oo +o00O0OoO +o00O0Ooo +o00O0o00 +o00oOOo +0o00oOOO +o00O0o0 +o00O0o0O +o00O0o0o +o00O0o +o00O0oO +o00O0oOO +o00O0oOo +o00O0oo0 +o00O0oo +0o00O0ooO +o00O0ooo +o00O +o00OO000 +o00OO00O +o00OO00o +o00OO0 +o00OO0O0 +o00OO0O +o00OO0OO +0o00OO0Oo +o00OO0o0 +o00OO0o +o00OO0oO +o00OO0oo +oo0O +o00OO +o00OOO00 +o00OOO0 +o00OOO0O +0o00OOO0o +o0o0Oo +o00OOO +o00OOOO0 +o00OOOO +o00OOOOo +oOooo0o +o00OOOo0 +o00OOOo +o00OOOoO +00o00OOOoo +0o00OOo00 +0o00OOo0 +0o00OOo0O +0o00OOo0o +0o00OOo +0o00OOoO0 +0o00OOoO +0o00OOoOO +0o00OOoOo +0o00OOoo0 +o00OOoo +o00OOooO +o00OOooo +o00OoOoO +o00Oo000 +o00Oo00 +o00Oo00o +o00Oo0O0 +o00Oo0O +0o00Oo0OO +o00Oo0Oo +o00Oo0o0 +o00Oo0o +o00Oo0oO +o00Oo0oo +o0oOO +o00Oo +o00OoO00 +o00OoO0 +0o00OoO0O +o00OoO0o +o00OoO +o00OoOO0 +o00OoOO +o00OoOOO +o00OoOOo +o00OoOo0 +o00OoOo +o00OoOoo +0o00Oooo0 +o00Ooo00 +o00Ooo0 +o00Ooo0O +o00Ooo0o +o00OooO0 +o00OooO +o00OooOO +o00OooOo +o0O00o0 +0o00Oooo +o00OoooO +o00Ooooo +o00o0000 +o00o000 +o00o000O +o00o000o +oo00oO +o00o00 +o00o00O0 +0o00o00OO +o00o00Oo +o00o00o0 +o00o00o +o00o00oO +o00o00oo +o00o0 +o00o0O00 +o00o0O0 +o00o0O0O +0o00o0O0o +o00o0OO0 +o00o0OO +o00o0OOO +o00o0OOo +o00o0Oo0 +o00o0Oo +o00o0OoO +o00o0Ooo +o00o0o00 +0o00o0o0 +o00o0o0O +o00o0o0o +o00o0o +o00o0oO0 +o00o0oO +o00o0oOO +o00o0oOo +o00o0oo0 +o00o0oo +0o00o0ooO +o00o0ooo +o00o +o00oo000 +o00oO000 +o00oO00O +o00oO00o +o00oOo +o00oO0 +o00oO0O0 +00o00oO0OO +0o00oO0Oo +0o00oO0o0 +0o00oO0oO +0o00oO0oo +0o00oO +0o00oOOoo +0o00oOO00 +0o00oOO0 +0o00oOO0O +0o00oOO0o +o0oOOo +o0ooOO +o00oOO +o00oOOO0 +o00oOOOO +o00oOOOo +o00oOOo0 +o00oOOoO +o00oOo00 +0o00oOo0 +o00oOooO +o00oOo0O +o00oOo0o +o00oOoO0 +o00oOoO +o00oOoOO +o00oOoOo +o00oOoo0 +o00oOooo +0o00oo00 +o00oo00O +o00oo0 +o00oo0OO +o00oo0O0 +o00oo0O +o00oo0Oo +o00oo0o0 +o00oo0o +o00oo0oO +0o00oo0oo +o0O0o +o00oo +o00ooO00 +o00ooO0 +o00ooO0O +o00ooO0o +o00ooO +o00ooOO0 +o00ooOO +0o00ooOOO +o00ooOOo +o00ooOo0 +o00ooOo +o00ooOoO +o00ooOoo +o00ooo00 +o00ooo0 +o00ooo0O +o00ooo0o +0o00oooO0 +o00oooO +o00oooOO +o00oooOo +o00oooo0 +o00oooo +o00ooooO +o00ooooo +o0 +o0O00000 +0o0O0000 +o0O0000O +o0O0000o +o0O000 +o0O000O +o0OoOoOo +o0O000Oo +o0OoOoOO +o0O000o0 +o0O000o +0o0O000oO +o0ooOoOO +o0O000oo +o0O00 +o0O00O0 +o0OoO00O +o0O00O0o +o0O00O +o0O00OO +o0O00OOO +0o0O00Oo0 +o0O00Oo +o0oO0Ooo +o0O00OoO +o0O00Ooo +o0O00o00 +o0O00o0O +o0O00o0o +o0O00o +o0O00oO0 +00o0O00oO +0o0O00oOO +0o0O00oOo +0o0O00oo0 +0o0Oo0oOO +0o0O00ooO +0o0O00ooo +0o0O0 +0o0ooOOOo +0o0O0O00O +0o0O0O0 +o0O0O0O +o0oO0O0o +o0O0oo0o +o0O0O0Oo +o0O0O0o0 +o0O0O0o +o0O0O0oO +o0O0O0oo +o0ooO +0o0O0O +o0O0OO0 +o0O0OO0O +o0O0OO +o0O0OOO0 +o0O0OOO +o0O0OOOo +o0O0OOo +o0O0OOoO +o0O0OOoo +0o0O0Oo00 +o0OooO0 +o0O0Oo0 +o0O0Oo0O +o0O0Oo0o +o0O0Oo +o0O0Oooo +o0O0OoO0 +oo0OOoo +o0O0OoO +0o0O0OoOO +o0O0OoOo +o0O0Ooo0 +o0O0Ooo +o0O0OooO +o0O0o000 +o0O0o00 +o0O0o00O +o0O0o00o +o0O0o0 +0o0O0o0O0 +o0O0o0O +o0O0o0OO +o0O0o0Oo +o0O0o0o0 +o0O0o0o +o0oOo0O0 +o0O0o0oO +o0O0o0oo +o0O0oo0O +0o0O0oO00 +oooOO0 +o0O0oO0 +o0O0oO0O +o0O0oO0o +o0O0oO +o0O0oOO0 +o0O0oOO +o0O0oo00 +o0O0oOOO +0o0O0oOOo +o0O0oOo0 +oo0oOOo +o0O0oOo +o0O0oOoO +o0O0oOoo +o0O0oo0 +o0O0oo +o0O0ooO0 +o0O0ooOO +0o0O0ooOo +o0O0ooo0 +o0O0ooo +o0O0oooO +o0O0oooo +o0O +o0OO000 +o0OO000o +oo0oO0 +oo0ooO +0o0OO00 +o0OO00OO +o0OO00oo +o0OO00Oo +o0OO00o0 +o0OoOoO +o0OO00o +o0OO0 +o0OO0O0 +o0OO0O0O +00o0OO0O0o +0o0OO0O +0o0OOoOOo +0o0OOoOoO +0o0OO0OO0 +0o0OO0OO +0o0OOoOO0 +0o0OO0OOO +0o0OO0OOo +0o0OO0Oo0 +0o0OO0Oo +o0OO0OoO +o0OOooO0 +o0OO0Ooo +o0OO0o00 +o0OO0o0 +o0OO0o0O +o0OO0o0o +o0OO0o +o0OO0oO0 +0o0OO0oo +o0OO0oO +o0OO0oOO +o0OOoooO +o0OO0oOo +o0OO0oo0 +o0OO0ooO +o0OO0ooo +o0OO +o0OOO00 +0o0OOO00O +o0OOO00o +o0OOO0 +o0OOO0O0 +o0OOO0O +o0OOO0OO +o0OOO0Oo +o0OOO0o0 +o0OOO0oO +o0OOO0oo +0o0OOO +o0OOOOoO +o0OOOO00 +o0OOOO0 +o0OOOO0o +o0OOOO +o0OOOOO0 +o0OOOOO +o0OOOOOO +o0OOOOOo +0o0OOOOo0 +o0OOOOo +o0OOOOoo +o0OOOo00 +o0OOOo0 +o0OOOo0O +o0OOOo0o +o0OOOo +o0OOOoO0 +o0OOOoO +0o0OOOoOO +o0OOOoOo +o0OOOoo0 +o0OOOoo +o0OOOooO +o0OOOooo +o0OOo000 +o0OOo00 +o0OOo00O +o0OOo00o +0o0OOo0 +o0OOo0O0 +o0OooOo +o0OOo0O +o0OOo0OO +o0OOo0Oo +o0OOo0o0 +o0OOo0o +o0OOo0oO +o0OOo0oo +0o0OOo +o0OOoO00 +o0OOoO0 +o0OOoO0O +o0OOoO0o +o0OOoO +o0OOoOO +o0OOoOOO +o0OOoOo0 +o0OOoOo +0o0OOoo00 +o0OOoo0 +o0OOoo0O +o0OOoo0o +o0OOoo +o0OOooO +o0OOooOO +o0OOooOo +o0OOooo0 +o0OOooo +00o0OOoooo +0o0Oo0000 +0o0Oo000 +0o0Oooo0O +0o0Oo00O0 +0o0Oo000O +0o0Oo000o +0o0Oo00 +0o0Oo00OO +0o0Oo00Oo +0o0oooOoo +o0Oo00o0 +o0Oo00o +o0Oo00oO +o0Oo00oo +o0Oo0 +o0ooO0O0 +o0Oo0O00 +o0Oo0O0 +o0Oo0O0O +0o0Oo0O0o +o0Oo0O +o0Oo0OO0 +o0Oo0OO +o0oOooO0 +o0ooOOOO +o0oOo000 +o0Oo0OOO +o0oOo0o0 +o0oOoo00 +0o0oO0OOo +o0Oo0OOo +o0Oo0Oo0 +o0Oo0Oo +o0Oo0OoO +o0Oo0oOo +o0Oo0Ooo +o0Oo0o00 +o0Oo0o0O +o0Oo0o0o +0o0Oo0o +o0Oo0oO0 +o0Oo0oO +o0Oo0oo0 +o0Oo0ooO +o0Oo0ooo +o0Oo +o0OooOoo +o0OoO000 +o0OoO0 +0o0OoO0O0 +o0oO0O00 +o0OoO0OO +o0ooOOO0 +o0OoO0Oo +o0OoO0o0 +o0OoO0oO +o0OoO0oo +o0OoO +o0OoOO00 +0o0OoOO0O +o0OoOO0o +o0OoOO +o0OoOOoO +o0OoOOO0 +o0OoOOO +o0OoOOOO +o0OoOOOo +o0OoOOo0 +o0OoOOo +0o0OoOOoo +o0OoOo00 +o0OoOo0O +o0ooOOoo +o0OoOo0o +o0OoOo +o0OoOoO0 +o0OoOoo0 +o0OoOoo +o0OoOooO +0o0OoOooo +o0Ooo000 +o0Ooo00 +o0Ooo00O +o0oOO0Oo +o0oOoOoo +o0Ooo00o +o0Ooo0 +o0Ooo0O0 +o0Ooo0O +0o0Ooo0OO +o0oOOOoo +o0OoooO0 +o0oOOO0o +o0Ooo0Oo +o0Ooo0o0 +o0Ooo0o +o0Ooo0oO +o0Ooo0oo +o0Ooo +00o0OooO00 +0o0OooO0O +0o0OooO0o +0o0OooO +0o0OooOO0 +0o0OooOO +0o0OooOOO +0o0OooOOo +0o0OooOo0 +0o0OooOoO +0o0Oooo00 +o0Oooo0 +o0Oooo0o +o0Oooo +o0OoooO +o0OoooOO +o0OoooOo +o0Ooooo0 +o0Ooooo +o0OooooO +0o0Oooooo +o0o0000 +o0o0o00O +o0o0000o +o0o000 +o0o000O0 +o0o000O +o0o000OO +o0o000Oo +o0o000o0 +0o0o000o +o0o000oO +o0o000oo +o0o00 +o0o00O00 +o0o00O0 +o0o00O0O +o0o00O0o +o0o00O +o0o00OO0 +0o0o00OO +o0o00OOO +o0o00OOo +o0o00Oo0 +o0o00Oo +o0o00OoO +o0o00Ooo +o0o00o00 +o0o00o0 +o0o00o0O +0o0o00o0o +o0o00o +o0o00oO0 +o0o00oO +o0o00oOO +o0o00oOo +o0o00oo0 +o0o00oo +o0o00ooO +o0o00ooo +0o0o0 +o0o0O000 +o0o0O00 +o0o0O00O +o0o0O00o +o0o0O0 +o0o0O0O0 +o0o0O0O +o0o0Oo00 +o0o0O0OO +0o0o0O0Oo +o0o0O0o0 +o0o0O0o +o0o0O0oO +o0o0O0oo +oO0Oo +oO0OO +o0ooo +o0o0O +o0o0OoO0 +0o0o0OO00 +o0o0OO0 +o0o0OO0O +o0o0OO0o +o0o0OO +o0o0OOO0 +o0o0OOO +o0o0OOOO +o0o0OOOo +o0o0OOo0 +0o0o0OOo +o0o0OOoO +o0o0OOoo +o0o0Oo0 +o0o0Oo0O +o0o0Oo0o +o0o0OoO +o0o0OoOO +o0o0OoOo +o0o0Ooo0 +000o0o0Ooo +00o0o0OooO +00o0o0Oooo +00o0o0o000 +00o0o0o00 +00o0o0o00o +00o0o0o0 +00o0o0o0O0 +00o0o0o0O +00o0o0o0OO +00o0o0o0Oo +0o0o0o0o0 +0o0o0o0o +0o0o0o0oO +0o0o0o0oo +0o0o0o +0o0o0oO00 +0o0o0oO0 +0o0o0oO0O +0o0o0oO0o +00o0oo00 +0o0o0oO +0o0o0oOO0 +0o0o0oOO +0o0o0oOOO +0o0o0oOOo +0o0o0oOo0 +0o0o0oOo +0o0o0oOoO +0o0o0oOoo +00o0o0oo00 +0o0o0oo0 +0o0o0oo0O +0o0o0oo0o +0o0o0oo +0o0o0ooO0 +0o0o0ooO +0o0o0ooOO +0o0o0ooOo +0o0o0ooo0 +00o0o0ooo +0o0o0oooO +0o0o0oooo +0o0o +0o0oO0000 +0ooooooO +0o0oO000 +0o0oO000O +0o0oO000o +0o0oO00 +00o0oO00O0 +0o0oO00O +0o0oO00Oo +0o0oO00OO +0o0oO00o0 +0o0oO00o +0o0oO00oO +0o0oO00oo +0o0oO0 +0o0oO0O0 +00o0oO0O +0o0oO0OO0 +0o0oO0OO +0o0oO0OOO +0o0oO0Oo +0o0oO0OoO +0o0oO0o00 +0o0oO0o0 +0o0oO0o0o +0o0oO0o0O +00o0oO0o +0o0oO0oO0 +0o0oO0oO +0o0oO0oOO +0o0oO0oo0 +0o0oO0oo +0o0oO0ooO +0o0oO0ooo +0o0oO +0o0oOO000 +00o0oOO00 +0o0oOO00O +0o0oOO00o +0o0oOO0 +0o0oOO0O0 +0o0oOO0O +0o0oOo0oO +0o0oOo0oo +0o0oOO0OO +0o0oOO0o0 +00o0oOO0o +0o0oOO0oO +0o0oOO0oo +0o0oOOO00 +0o0oOOO0 +0o0oOOO0O +0o0oOOO +0o0oOOOO0 +0o0oOOOO +0o0oOOOOO +00o0oOOOOo +0o0oOOOo0 +0o0oOOOo +0o0oOOOoO +0o0oOOo00 +0o0oOOo0 +0o0oOOo0O +0o0oOOo0o +0o0oOOoO0 +0o0oOOoO +0o0oOoO00 +o0oOOoOO +o0oOooOO +o0oOOoOo +o0oOOoo0 +o0oOOoo +o0oOOooO +o0oOOooo +o0oOo00 +o0oOo00O +0o0oOo00o +o0oOo0 +o0oOo0O +o0oOo0OO +o0oOo0Oo +o0oOo0o +o0oOo +o0oOoO0 +o0oOoO0o +o0oOoOo0 +0o0oOoO0O +o0oOoO +o0oOoOO0 +o0oOoOO +o0oOoOOO +o0oOoOOo +o0oOoOo +o0oOoOoO +o0oOoo0 +o0oOoo0O +0o0oOoo0o +o0oOoo +o0oOooO +o0oOooOo +o0oOooo0 +o0oOooo +o0oOoooO +o0oOoooo +o0oo0000 +o0oo000O +0o0oo000o +o0oo00O0 +o0oo00O +o0oo00OO +o0oo00Oo +o0oo00o0 +o0oo00o +o0oo00oO +o0oo00oo +o0oo0 +0o0oo0O00 +o0oo0O0 +o0oo0O0O +o0oo0O0o +o0oo0o +o0oo0O +o0oo0OO0 +o0oo0OO +o0oo0OOO +o0oo0OOo +0o0oo0Oo0 +o0oo0Oo +o0oo0OoO +o0oo0Ooo +o0oo0o00 +o0oo0o0 +o0oo0o0O +o0oo0o0o +o0oo0oO0 +o0oo0oO +0o0oo0oOO +o0oo0oOo +o0oo0oo0 +o0oo0oo +o0oo0ooO +o0oo0ooo +o0ooO000 +o0ooO00 +o0ooO00O +o0ooO00o +0o0ooO0 +o0ooO0O +o0ooO0OO +o0ooO0Oo +o0ooO0o0 +o0ooO0o +o0ooO0oO +o0ooO0oo +o0ooOO0O +o0ooOO0o +00o0ooOOO +0o0ooOOoO +0o0ooOo00 +0o0ooOo0 +0o0ooOo0o +0o0ooOo0O +0o0ooOo +0o0ooOooO +0o0ooOoO0 +0o0ooOoOo +0o0ooOoo0 +o0ooOoo +o0ooOooo +o0ooo000 +o0ooo00O +o0ooo00o +o0ooo0 +o0ooo0O +o0ooo0o0 +o0ooo0o +0o0ooo0oO +o0ooo0oo +o0oooO00 +o0oooO0 +o0oooO0o +o0oooO0O +o0oooO +o0oooOO0 +o0oooOO +o0oooOOo +0o0oooOOO +o0oooOo0 +o0oooOo +o0oooOoO +o0oooo00 +o0oooo0 +o0oooo0O +o0oooo0o +o0oooo +o0ooooO0 +0o0ooooO +o0ooooOo +o0ooooo0 +ooo0Oo0 +o0ooooo +o0oooooO +o0oooooo +o +oO00000 +oO00000o +0oO0000 +oO0000O +oO0000Oo +oO0000o0 +oO0000o +oO0000oO +oO0000oo +oO000 +oO000O0 +oO000O0O +0oO0Ooo00 +oO0Ooooo +oO000O0o +oO0o0o +oO000O +oO0OoOO0 +oO0OOooo +oO0OoOOO +oO0OOoO0 +oO0Oo0oo +0oO000OOO +oO0OO0oo +oO0OOooO +oO000OOo +oO0OoOoO +ooOOOOoo +oO0OOo0o +oO000Oo0 +oO000Oo +oO0OO0OO +0oO0OoOoo +oO0OOoo0 +oO000OoO +oO0OOo0O +oO000Ooo +oO000o00 +oO000o0 +ooOOOOOo +oO000o0o +oO000o +0oO0Oo0OO +oO000oO0 +oO000oO +oO0Ooo0O +oO000oOO +oO0Ooo0o +oO000oOo +oO000oo0 +oO000oo +oO0Oo0Oo +00oO000ooO +0oO0Oo0O0 +0oO000ooo +0oO00 +0oO00O00 +0oO0O0o0o +0ooOOoooO +0oO00O00o +0oO00O0 +0oO00O0O +0oO00O0Oo +oO0O0OoO +ooOOooOo +oO00O0o0 +oO00O0o +oOo00OO0 +oO00O0oO +oO0O0OOo +oO00O0oo +oO00O +0oO00OO0 +ooOOoOoO +oO0O0OOO +oO00OO0O +oO00OO +oO00OOO +oO00OOOo +oOo00Oo0 +ooOOoOOo +oO00OOo0 +0oO00OOo +oO0oOOO0 +oO00OOoO +oOOoOoOO +oO00OOoo +oO00Oo00 +oO00Oo0 +oO00Oo0O +oO00Oo0o +oO00Oo +0oO00oOOO +oO00OoO0 +oO00OoO +oOOoOOO0 +oO00OoOO +oO0oOOOo +oO00OoOo +oO00Ooo0 +oO00Ooo +oO00OooO +0oO00Oooo +oO0OOoOo +oO00o000 +oO00o00 +oO0OooOO +oO0OoOo0 +oO0OOO00 +oO00o00O +oO0OOoOO +oO00o00o +0ooOO0O +ooOOo0 +oO00o0 +oO0OOOoo +oO00o0O0 +oO00o0O +oO0OOOOo +oO00o0OO +oO0OOOoO +oO00o0Oo +0oO0OoO0O +oO0OOO0o +oO00o0o0 +oO00o0o +oO0OOOo0 +oO00o0oO +oO0OOO0O +oO00o0oo +oO00o +oO0OO0oO +0oO0OO000 +oOo00o0o +oO00oO00 +oO00oO0 +oO0OoooO +oOo00ooO +oO00oO0O +oO0OooOo +oOo00ooo +oO00oO0o +0oO00oO +oO00oOO0 +oO00oOO +oO0OO00o +oO00oOOo +oOo00oO0 +oO00oOo0 +oO00oOo +oO0OO00O +ooOOOOoO +00oOo00oOO +0oO00oOoO +0oOo00oOo +0oO00oOoo +0oO0OOOOO +0oO00oo00 +0oO00oo0 +0oO0OO0o0 +0oO00oo0O +0oO00oo0o +0oO00oo +oO00ooO0 +oO00ooO +oOo000Oo +oO00ooOO +oO00ooOo +oOo0000O +oO00ooo0 +oO00ooo +oOo000oo +0oO00oooO +oOo000o0 +oO00oooo +oO0 +oO0O000 +oO0Oo00O +ooOOoOo0 +oO0O000o +oO0O00 +oO0O00O +0oO0O00Oo +oO0O00o0 +oO0O00o +oO0O00oO +oO0O00oo +oOoo0 +oO0O0 +oO0O0O00 +oO0O0O0 +ooOOOoO0 +0oO0O0O0O +ooOOOoo0 +oO0O0O0o +oO0O0o +oO0O0O +oO0O0OO +oOo0oooO +ooOOOoOo +oO0O0Oo0 +oO0O0Oo +0oO0O0o0 +oO0O0o0O +oO0O0oO0 +oO0O0oO +oOo0o0oO +ooOOO0Oo +oO0O0oOO +oO0O0oOo +oOo00OOo +oO0O0oo0 +0oO0O0oo +oOo00OOO +ooOOO00O +oO0O0ooO +oO0O0ooo +ooo0o +oO0O +oO0OO00 +oO0OO0O +oO0OO0Oo +0oO0OO0o +oO0OOO0 +oO0OOO +oO0OooO0 +oO0OOOO0 +oO0OOOO +oO0OOOo +oO0OOo0 +oO0OOo +oO0OOoO +0oO0OOoo +oO0Oo00 +oO0Oo0 +oO0Oo0O +oO0Oo0o0 +oO0Oo0o +oO0OoO00 +oO0OoO0 +oO0OoO +oO0OoOO +0oO0OoOo +oO0Ooo0 +oO0Ooo +oO0OooO +oO0Oooo +oO0o0000 +oO0o000 +oO0o000O +ooOOoOoo +oO0o000o +00oO0o00 +0oO0o0oo0 +0oO0o00O0 +0oO0o00O +0oO0o00OO +0oO0o00Oo +0oO0o00o0 +0oO0o00o +0oO0o00oO +0oO0o00oo +0oO0o0 +oO0o0O00 +oO0o0O0 +oO0o0O0O +oO0o0O0o +oO0o0O +oO0o0OO0 +oO0o0OO +oO0o0OOO +oO0o0OOo +0oO0o0Oo0 +oO0o0Oo +oO0o0OoO +oO0o0Ooo +oO0o0o00 +oO0o0o0 +oO0o0o0O +oO0o0o0o +oO0o0oO0 +oO0o0oO +0oO0o0oOO +oO0o0oOo +oO0o0oo +oO0o0ooO +oO0o0ooo +oO0o +oO0oO000 +oO0oO00 +oOo00O0O +ooOOoOO0 +0oO0oO00O +oO0oO00o +oO0oO0 +oO0oO0O0 +oO0oO0O +oO0oO0OO +oOo00OoO +ooOOoOOO +oO0oO0Oo +oO0oO0o0 +0oO0oO0o +oO0oO0oO +oO0oO0oo +oOooo +oO0oO +oO0oOoOO +oO0oOO00 +oO0oOO0 +oO0oOO0O +oO0oOO0o +0oO0oOO +oO0oOOO +oO0oOOOO +oO0oOOo0 +oO0oOOo +oO0oOOoO +oO0oOOoo +oO0oOo00 +oO0oOo0 +oO0oOo0O +0oO0oOo0o +oO0oOo +oO0oOoO0 +oO0oOoO +oO0oOooo +oO0oOoOo +oO0oOoo0 +oO0oOoo +oO0oOooO +oO0oo000 +0oO0oo00 +oO0oo00O +oO0oo00o +oO0oo0 +oO0oo0O0 +oO0oo0O +oO0oo0OO +oO0oo0Oo +oO0oo0o0 +oO0oo0o +0oO0oo0oO +oO0oo0oo +oO0oo +oO0ooO00 +oO0ooO0 +oO0ooO0O +oO0ooO0o +oO0ooO +oO0ooOO0 +oO0ooOO +00oO0ooOOO +0oO0ooOOo +0oO0ooOo0 +0oO0ooOo +0oO0ooOoO +0oO0ooOoo +0oO0ooo00 +0oO0ooo0 +0oO0ooo0O +0oO0ooo0o +0oO0ooo +oOo00o0O +oO0oooO0 +oO0oooO +oO0oooOO +oOo00oo0 +oO0oooOo +oOo000OO +oO0oooo0 +oO0oooo +0oO0ooooO +oOo00o00 +oO0ooooo +oO +oOO00000 +oOO0000 +oOO0000O +oOO0000o +oOO000 +oOO000O0 +0oOO000O +oOO000OO +oOO000Oo +oOO000o0 +oOO000o +oOO000oO +oOO000oo +oOO00 +oOO00O00 +oOO00O0 +0ooooOO00 +oOO00O0O +oOO00O0o +oOO00OO0 +oOO00OO +oOO00OOO +oOO00OOo +oOO00Oo0 +oOO00Oo +ooooO000 +0oOO00OoO +ooooOoOo +oOO00Ooo +oOO00o00 +oOO00o0 +oOO00ooo +oOO00o0O +oOO00o0o +oOO00o +oOO00oO0 +0oOO00oO +ooooOOo0 +ooooO0oo +oOO00oOO +oOO00oOo +oOO00oo +oOO00ooO +oOO0 +ooooOoOO +oOO0O000 +0oOO0O00 +oOO0O00O +oOO0O00o +oOO0O0 +oOO0O0O0 +oOO0O0O +oOO0O0OO +oOO0O0Oo +oOO0O0o0 +oOO0O0o +0oOO0O0oO +oOO0O0oo +oOO0O +oOO0OO0 +oOO0OO0O +oOO0OO0o +oOO0OO +oOO0OOO +oOO0OOOO +oOO0OOOo +0oOO0OOo0 +oOO0OOo +oOO0OOoO +oOO0OOoo +oOO0Oo00 +oOO0Oo0 +oOO0Oo0O +oOO0Oo0o +oOO0Oo +oOO0OoO0 +00oOO0OoO +0oOO0OoOO +0oOO0OoOo +0oOO0Ooo0 +0oOO0Ooo +0oOO0OooO +0oOO0Oooo +0oOO0o00 +0ooooOOoo +0oOO0o00o +0oOO0o0 +oOO0o0O0 +oOO0o0O +oOO0o0OO +oOO0o0Oo +ooooO0O0 +oOO0o0o0 +oOO0o0o +oOO0o0oO +oOO0o0oo +0oOO0o +oOO0oO00 +oOO0oO0 +oOO0oO0O +oOO0oO0o +oOO0oO +oOO0oOO0 +oOO0oOO +oOO0oOOO +oOO0oOOo +0oOO0oOo0 +oOO0oOo +oOO0oOoO +oOO0oOoo +oOO0oo00 +oOO0oo0 +oOO0oo0O +oOO0oo0o +oOO0oo +oOO0ooO0 +0oOO0ooO +oOO0ooOO +oOO0ooOo +oOO0ooo0 +oOO0ooo +oOO0oooO +oOO0oooo +oOO +oOOO000 +oOOO000o +0oOOO0O +oOOOoO +oOOO00 +oOOO00O +oOOO00Oo +oOOO00o0 +oOOO00o +oOOO00oO +oOOO00oo +oOOO0 +0oOOO0oOO +oOOO0O0 +oOOO0O0o +oOOO0OO0 +oOOO0OO +oOOO0OOO +oOOO0OOo +oOOO0Oo +oOOO0OoO +oOOO0Ooo +0oOOO0o00 +oOOO0o0 +oOOO0o0O +oOOO0o0o +oOOOOO +oOOO0o +oOOO0oO0 +oOOO0oO +oOOO0ooo +oOOO0ooO +0oOOO0oOo +oOOO0oo0 +oOOO0oo +oOOO +oOOOO0OO +oOOOO000 +oOOOO00 +oOOOoo00 +oOOOO00O +oOOOO00o +0oOOOO0 +oOOOO0O0 +oOOOO0O +oOOOO0Oo +oOOOO0o0 +oOOOO0o +oOOOO0oO +oOOOO0oo +oOo0o +oOOOO +00oOOOOO00 +0oOOOOO0 +0oOOOOO0O +0oOOOOO0o +0oOOOOOO0 +0oOOOOOO +0oOOOOOOO +0oOOOOOOo +0oOOOOOo0 +0oOOOOOo +0oOOOOOoO +oOOOOOoo +oOOOOo00 +oOOOOo0 +oOOOOo0O +oOOOOo0o +oOOOOo +oOOOOoO0 +oOOOOoO +oOOOOoOO +0oOOOOoOo +oOOOOoo0 +oOOOOoo +oOOOOooO +oOOOOooo +oOOOo000 +oOOOo00 +oOOOo00O +oOOOo00o +oOOOo0 +0oOOOo0O0 +oOOOo0O +oOOOo0OO +oOOOo0Oo +oOOOo0o0 +oOOOo0o +oOOOo0oO +oOOOo0oo +oOOOo +oOOOoO00 +0oOOOoO0 +oOOOoO0O +oOOOoO0o +oOOOoOO0 +oOOOoOO +oOOOoOOO +oOOOoOOo +oOOOoOo0 +oOOOoOo +oOOOoOoO +0oOOOoOoo +oOOOoo0 +oOOOoo0O +oOOOoo0o +oOOOoo +oOOOooO0 +oOOOooO +oOOOooOO +oOOOooOo +oOOOooo0 +0oOOOooo +oOOOoooO +oOOOoooo +oOOo0000 +oOOo000 +oOOo000O +oOOo000o +oOOo00 +oOOo00O0 +oOOo00O +0oOOo00OO +oOOo00Oo +oOOo00o0 +oOOo00o +oOOo00oO +oOOo00oo +oOOo0 +oOOo0O00 +oOOo0O0 +oOOo0O0O +0oOOo0O0o +oOOo0O +oOOo0OO0 +oOOo0OO +oOOo0OOO +oOOo0OOo +oOOo0Oo0 +oOOo0Oo +oOOo0OoO +oOOo0Ooo +0oOOo0o00 +oOOo0o0 +oOOo0o0O +oOOo0o0o +oOOo0o +oOOo0oO0 +oOOo0oO +oOOo0oOO +oOOo0oOo +oOOo0oo0 +00oOOo0oo +0oOOo0ooO +0oOOo0ooo +0oOOo +0oOOoO000 +0oOOoO00 +0oOOoO00O +0oOOoO00o +0oOOoO0 +0oooO0oOO +0oOOoO0O0 +oOOoO0O +oOOoO0OO +oOOoO0Oo +oOOoO0o +oOOoO0oO +oOOoO0oo +oOOoO +oOOoOO0o +oOOoOO00 +0oOOoOO0 +oOOoOO0O +oOOoOOO +oOOoOOOO +oOOoOOOo +oOOoOOo0 +oOOoOOo +oOOoOOoO +oOOoOOoo +oOOoOo00 +0oOOoOo0 +oOOoOo0O +oOOoOo0o +oOOoOo +oOOoOoO0 +oOOoOoO +oOOoOoOo +oOOoOoo0 +oOOoOoo +oOOoOooO +0oOOoOooo +oOOoo000 +oOOoo00 +oOOoo00O +oOOoo00o +oOOoo0 +oOOoo0O0 +oOOoo0O +oOOoo0OO +oOOoo0Oo +0oOOoo0o0 +oOOoo0o +oOOoo0oO +oOOoo0oo +oOOoo +oOOooO00 +oOOooO0 +oOOooO0O +oOOooO0o +oOOooO +0oOOooOO0 +oOOooOO +oOOooOOO +oOOooOOo +oOOooOo0 +oOOooOo +oOOooOoO +oOOooOoo +oOOooo00 +oOOooo0 +0oOOooo0O +oOOooo0o +oOOooo +oOOoooO0 +oOOoooO +oOOoooOO +oOOoooOo +oOOoooo0 +oOOoooo +oOOooooO +0oOOooooo +oOo0000 +oOo000 +oOo000O +oOo000o +oOo00O0 +oOo00O +oOo00OO +oOo0o00 +oOo00Oo +0oOo00o0 +oOo00o +oOo00oO +oOo00oo +oOo0 +oOo0O000 +oOo0O00 +oOo0O00O +oOo0oO0o +oOo0O00o +000oOo0oo +00oOo0O0 +00oOo0O0O0 +00oOo0O0O +00oOo0O0OO +00oOo0O0Oo +00oOo0O0o0 +00oOo0O0o +00oOo0O0oO +00oOo0O0oo +00oOo0O +0oOo0OO00 +0oOoo00o +0oOo0OO0 +0oOo0OO0O +0oOo0OO0o +0oOo0OO +0oOo0OOO0 +0oOo0OOO +0oOo0OOOO +00oOo0OOOo +0oOo0OOo0 +0oOo0OOo +0oOo0OOoO +0oOo0OOoo +0oOo0Oo00 +0oOo0Oo0 +0oOo0Oo0O +0oOo0Oo0o +0oOo0Oo +00oOo0OoO0 +0oOo0OoO +0oOo0OoOO +0oOo0OoOo +0oOo0Ooo0 +0oOo0Ooo +0oOo0OooO +0oOo0Oooo +0oOo0o000 +0oOo0o00O +00oOo0o00o +0oOo0o0 +0oOo0o0O +0oOo0o0OO +0oOo0o0Oo +0oOo0o0o0 +0oOo0o0o +0oOo0oO00 +0oOo0oO0 +0oOo0oO0O +00oOo0oO +0oOo0oOO0 +0oOo0oOO +0oOo0oOOO +0oOo0oOOo +0oOo0oOo0 +0oOo0oOo +0oOo0oOoO +0oOo0oOoo +0oOo0oo00 +00oOo0oo0 +0oOo0oo0O +0oOo0ooO0 +0oOo0ooO +0oOo0ooOO +0oOo0ooOo +0oOo0ooo0 +0oOo0ooo +0oOo +0oOooOOoO +00oOoO0000 +0oOoO000 +0oOoO000O +0oOoO000o +0oOoO00 +0oOoO00O0 +0oOoO00O +0oOoO00OO +0oOoO00Oo +0oOoO00o0 +00oOoO00o +0oOoO00oO +0oOoO00oo +0oOoO0 +0oOooOo0O +0oOoO0O00 +0oOoO0O0 +0oOoO0O0O +0oOoO0O0o +0oOoO0o +00oOoO0O +0oOoO0OO0 +0oOoO0OO +0oOoO0OOO +0oOoO0OOo +0oOoO0Oo0 +0oOoO0Oo +0oOoO0OoO +0oOoO0Ooo +0oOooOo00 +00oOoO0o00 +0oOoO0o0 +0oOoO0o0O +0oOoOoOOO +0oOoO0o0o +0oOoO0oO0 +0oOoO0oO +0oOoO0oOO +0oOoO0oOo +0oOooOo0o +0oOoO0oo0 +oOoO0oo +oOoO0ooO +oOoO0ooo +oOoO +oOoOO000 +oOoOO00 +oOoOO00O +oOoOO00o +oOoOO0 +0oOoOO0O0 +oOoOO0O +oOoOOo0O +oOoOO0OO +oOoOO0Oo +oOoOO0o0 +oOoOO0o +oOoOO0oO +oOooOOOO +oOoOO0oo +0oOoOO +oOoOOO00 +oOoOOO0 +oOoOOO0O +oOoOOO0o +oOoOOO +oOoOOOO0 +oOoOOOO +oOoOOOOO +oOoOOOOo +0oOoOOOo0 +oOoOOOo +oOoOOOoO +oOooOooO +oOoOOOoo +oOoOOo00 +oOoOOo0 +oOoOOo0o +oOoOOo +oOoOOoO0 +0oOoOOoO +oOoOOoOO +oOoOOoOo +oOoOOoo0 +oOoOOoo +oOoOOooO +oOoOOooo +oOoOo000 +oOoOo00 +oOoOo00O +0oOoOo00o +oOoOo0 +oOoOoo0O +oOoOo0O0 +oOoOo0O +ooOOO0oo +oOooo0Oo +oOooo0oo +oOoOo0OO +ooOOO0o0 +0oOoOo0Oo +oOoOo0o0 +oOoOo0o +oOoOo0oO +oOoOo0oo +oOoOo +ooOOOooo +oOoOoO00 +oOoOoO0 +oOoOoO0O +0ooOOOooO +oOooooOO +oOoOoO0o +oOoOoO +oOoOoOO0 +oOoOoOO +oOoOoOOo +oOoOoOo0 +oOoOoOo +oOooOOoo +0oOoOoOoO +oOoOoOoo +ooOOO0oO +oOooo0oO +oOoOoo00 +oOoOoo0 +ooOOO0O0 +oOooo0O0 +oOoOoo0o +oOoOoo +00ooOOOo0o +0oOoooooo +0oOoOooO0 +0oOoOooO +0oOoOooOO +0ooOOOo0O +0oOoooooO +0oOoOooOo +0oOoOooo0 +0oOoOooo +0ooOOOo00 +oOooooo0 +oOoOoooO +oOoOoooo +oOoo0000 +oOoo000 +oOoo000O +oOoo000o +oOoo00 +oOoo00O0 +0oOoo00O +oOoo00OO +oOoo00Oo +oOoo00o0 +oOoo00oO +oOoo00oo +oOoo0Oo0 +oOoo0O00 +oOoo0O0 +oOoo0O0O +0oOoo0O0o +oOoo0O +oOoo0OO0 +oOoo0oO +oOooo00 +oOoo0OO +oOoo0OOO +oOoo0OOo +oOoo0Oo +oOoo0OoO +0oOoo0Ooo +oOoo0o00 +oOoo0o0 +oOoo0o0O +oOoo0o0o +oOoo0o +oOoo0oO0 +oOoo0oOO +oOoo0oOo +oOoo0oo0 +0oOoo0oo +oOoo0ooO +oOoo0ooo +oOoo +oOooO000 +oOooO00 +oOooO00O +oOooO00o +oOooO0 +oOooO0O0 +0oOooO0O +oOooO0OO +oOooO0Oo +oOooO0o0 +oOooO0o +oOooO0oO +oOooO0oo +oOooO +oOooOO00 +oOooOO0 +0oOooOOo0 +oOooOO0O +oOooOO0o +oOooOO +oOooOOO0 +oOooOOO +oOooOOOo +oOooOOo +oOooOo0 +oOooOo +0oOooOoO0 +oOooOoO +oOooOoOO +oOooOoOo +oOooOoo0 +oOooOoo +oOooOooo +oOooo000 +oOooo00O +oOooo00o +0oOoooO +oOooo0 +oOooo0O +oOooo0OO +oOooo0o0 +oOoooO00 +oOoooO0 +oOoooO0O +oOoooO0o +oOoooOO0 +00oOoooOO +0oOoooOOO +0oOoooOOo +0oOoooOo0 +0oOoooOo +0oOoooOoO +0oOoooOoo +0oOoooo00 +0oOoooo0 +0oOoooo0O +0oOoooo0o +oOoooo +oOooooO0 +oOooooO +oOooooOo +oOooooo +oo000000 +oo00000 +oo00000O +oo00000o +0oo0000 +oo0000O0 +oo0000O +oo0000OO +oo0000Oo +oo0000o0 +oo0000o +oo0000oO +oo0000oo +oo000 +0oo000O00 +oo000O0 +oo000O0O +oo000O0o +oo000O +oo000OO0 +oo0OOOO +oo000OO +oo000OOO +oo000OOo +0oo000Oo0 +oo000Oo +oo000OoO +oo000Ooo +oo000o00 +oo000o0 +oo000o0O +oo000o0o +oo000oO0 +oo000oO +0oo000oOO +oo000oOo +oo000oo0 +oo000oo +oo000ooO +oo00 +oo00O00o +oo00O000 +oo00O00 +oo00O00O +0oo00O0 +oo00O0O0 +oo00O0O +oo00Oo0O +oo00O0OO +oo00O0Oo +oo00O0o0 +oo00O0o +oo00O0oO +oo00O0oo +0oo00O +oo00OO00 +oo00OO0 +oo00OO0O +oo00OO0o +oo00OO +oo00OOO0 +oo00OOO +oo00OOOO +oo00OOOo +0oo00OOo0 +oo00OOo +oo00OOoO +oo00OOoo +oo00Oo00 +oo00Oo0 +oo00Oo0o +oo00Oo +oo00OoO0 +oo00OoO +0oo00OoOO +oo00OoOo +oo00Ooo0 +oo00Ooo +oo00OooO +oo00Oooo +oo00o000 +oo00o00 +oo00o0o0 +oo00o00O +00oo00o00o +0oo00o0 +0oo00o0oo +0oo00ooOO +0oo00o0O0 +0oo00o0O +0oo00o0OO +0oo00o0Oo +0oo00o0o +0oo00o0oO +0oo00oO00 +oo00oO0 +oo00oO0O +oo00oO0o +oo00oOoO +oo00oOO0 +oo00oOo +oo00oOO +oo00oOOO +oo00oOOo +0oo00oOo0 +oo00oOoo +oo00oo00 +oo00oo0 +oo00oo0O +oo00oo0o +oo00oo +oo00ooO0 +oo00ooO +oo00ooOo +0oo00ooo0 +oo00ooo +oo00oooO +oo00oooo +oo0 +oo0O0000 +oo0O000 +oo0O000O +oo0O000o +oo0O00 +0oo0oOOOO +oo0O00O0 +oo0O00O +oo0O00OO +oo0O00Oo +oo0O00o0 +oo0O00o +oo0O00oO +oo0O00oo +oo0O0 +0oo0O0O00 +oo0O0O0 +oo0O0O0O +oo0O0O0o +oo0O0O +oo0O0OO0 +oo0O0OO +oo0O0OOO +oo0O0OOo +oo0O0Oo0 +0oo0O0Oo +oo0O0OoO +oo0O0Ooo +oo0O0o00 +oo0O0o0 +oo0O0o0O +oo0O0o0o +oo0O0o +oo0O0oO0 +ooo0OoO +0oo0O0oO +oo0oOOoO +oo0O0oOO +oo0O0oOo +oo0O0oo0 +oo0O0oo +oo0O0ooO +oo0O0ooo +oo0OoOO0 +oo0OO00o +0oo0OO00O +oo0OO000 +oo0OO00 +oo0Oo0 +oo0Ooo +oo0OoO +oo0OO0 +oo0OOoOO +oo0OO0Oo +oo0OOo0O +0oo0OOooO +oo0OO0O0 +oo0OO0O +oo0OO0OO +oo0OO0o0 +oo0OO0o +oo0OO0oO +oo0OO0oo +oo0OO +oo0OOO00 +00oo0oOoo +0oo0OOO0 +0oo0OOO0O +0ooo000O0 +0oo0OOO0o +0oo0OOO +0ooo000o0 +0oo0OOOO0 +0oo0OOOOO +0oo0OOOOo +0oo0OOOo0 +oo0OOOo +oo0OOOoO +ooo0000O +ooo00000 +oo0OOOoo +oo0OOo00 +oo0OOo0 +oo0OOo0o +oo0OOo +0oo0OOoO0 +oo0OOoO +oo0OOoOo +oo0OOoo0 +oo0OOooo +oo0Oo000 +oo0Oo00 +oo0Oo00O +oo0Oo00o +oo0Oo0O0 +0oo0Oo0O +oo0Oo0OO +oo0Oo0Oo +oo0Oo0o0 +oo0Oo0o +oo0Oo0oO +oo0Oo0oo +oo0Oo +oo0OoO00 +oo0OoO0 +0oo0OoO0O +oo0OoO0o +oo0OoOO +oo0OoOOO +oo0OoOOo +oo0OoOo0 +oo0OoOo +oo0OoOoO +oo0OoOoo +oo0Ooo00 +0oo0Ooo0 +oo0Ooo0O +oo0Ooo0o +oo0OooO +oo0OooOO +oo0OooOo +oo0Oooo0 +oo0Oooo +oo0OoooO +0oo0Ooooo +oo0o0000 +oo0o000 +oo0o000O +oo0o000o +oo0o00 +oo0o00O0 +oo0o00o +oo0o00O +oo0o00Oo +0oo0o00oO +oo0o00OO +oo0o00o0 +oo0o00oo +oo0o0 +oo0o0O00 +oo0o0O0o +oo0o0o +oo0o0O +oo0o0OO0 +0oo0o0OO +oo0o0OOO +oo0o0OOo +oo0o0Oo0 +oo0o0OoO +oo0o0Ooo +oo0o0o00 +oo0o0o0 +oo0o0o0O +oo0o0o0o +0oo0o0oO0 +oo0o0oO +oo0o0oOO +oo0o0oOo +oo0o0oo0 +oo0o0oo +oo0o0ooO +oo0o0ooo +oo0o +oo0oO000 +00oo0oO00 +0oo0oO0oO +0oo0oO00O +0oo0oO00o +0oo0oO0O0 +0oo0oO0O +0oo0oO0OO +0oo0oO0Oo +0oo0oO0o0 +0oo0oO0o +0oo0oO0oo +oo0oO +oo0oOO00 +oo0oOO0O +oo0oOO0o +oo0oOO +oo0oOOO0 +oo0oOOO +oo0oOOOo +oo0oOOo0 +0oo0oOOoo +oo0oOo00 +oo0oOo0 +oo0oOo0O +oo0oOo0o +oo0oOo +oo0oOoO0 +oo0oOoOO +oo0oOoOo +oo0oOoo0 +0oo0oOooO +oo0oOooo +oo0oo000 +ooo0oOO +oooOooO +oo0oo00 +oo0oo00O +oo0oo00o +oo0oo0 +oo0oo0O0 +0oo0oo0O +oo0oo0OO +oo0oo0Oo +oo0oo0o0 +oo0oo0o +oo0oo0oO +oo0oo0oo +oo0oo +oo0ooO00 +oo0ooO0 +0oo0ooO0O +oo0ooO0o +oo0ooOO0 +oo0ooOO +ooo0O0oo +ooo0oooO +oo0ooOOO +oo0ooOOo +oo0ooOo0 +oo0ooOo +0oo0ooOoO +oo0ooOoo +oo0ooo00 +oo0ooo0 +oo0ooo0o +oo0ooo0O +oo0ooo +oo0oooOO +oo0oooO0 +oo0oooO +0oo0oooOo +oo0oooo0 +oo0oooo +oo0ooooO +oo0ooooo +oo +ooO00000 +oooooOo +ooO0000 +ooO0000O +0ooOooOOO +ooO0000o +ooO0oo +ooO000 +ooO000O0 +ooO000O +ooO000OO +ooO000Oo +ooO000o0 +ooO000o +0ooO000oO +ooO000oo +ooO00 +ooO0OOoo +ooOo000o +ooOo00O0 +ooO00O00 +ooO00O0O +ooO0OOoO +ooO00O0o +00ooO00O +0ooOo00o0 +0ooO00OO0 +0ooO00OO +0ooO0OOOO +0ooO00OOO +0ooO00OOo +0ooO00Oo0 +0ooO00Oo +0ooO00OoO +0ooOo00OO +ooO00Ooo +ooO00o00 +ooO00o0 +ooO00o0O +ooO00o0o +ooO00o +ooO00oO0 +ooO00oO +ooO00oOO +0ooO00oOo +ooO00oo0 +ooO00oo +ooO00ooO +ooO00ooo +ooO0 +ooO0O000 +oooo000 +ooO0O00 +ooO0O00O +0ooO0O00o +ooO0O0 +ooO0O0O0 +ooO0O0O +ooO0O0OO +ooO0O0Oo +ooO0O0o0 +ooO0OOO +ooO0O0o +ooO0O0oO +0ooO0O0oo +ooO0O +ooOo000O +ooO0OO00 +ooO0OO0 +ooO0OO0O +ooO0OO0o +ooO0OO +ooO0OOO0 +ooO0OOOo +0ooO0OOo0 +ooO0OOo +ooO0Oo00 +ooo0oOo +ooO0Oo0 +ooO0Oo0O +ooO0Oo0o +ooO0Oo +ooO0OoO0 +ooO0OoO +0ooO0OoOO +ooO0OoOo +ooO0Ooo0 +ooO0OooO +ooO0Oooo +ooO0o000 +ooO0o00 +ooO0o00O +ooO0o00o +ooO0o0 +0ooO0o0O0 +ooO0o0O +ooO0o0OO +ooO0o0Oo +ooO0o0o0 +ooO0o0o +ooO0o0oO +ooO0o0oo +ooO0o +ooO0oO00 +0ooO0oO0 +ooO0oO0O +ooOo00Oo +ooO0oO0o +ooO0oO +ooO0oOO0 +ooO0oOO +ooO0oOOO +ooO0oOOo +ooO0oOo0 +0ooo0OOo +ooO0oOo +ooO0oOoO +ooO0oOoo +ooO0oo00 +ooO0oo0 +ooO0oo0O +ooO0oo0o +ooO0ooO0 +ooO0ooO +00ooO0ooOO +0ooO0ooOo +0ooO0ooo0 +0ooO0ooo +0ooO0oooO +0ooO0oooo +0ooo +0ooO +0ooOO0000 +0ooOO000 +0ooOO000O +ooOO000o +ooOO00 +ooOO00O0 +ooOO00O +ooOO00OO +ooOO00Oo +ooOO00o0 +ooOO00o +ooOO00oO +0ooOO00oo +ooOO0 +ooOO0O00 +ooOO0O0 +ooOO0O0O +ooOO0O0o +ooOO0OO0 +ooOO0OO +ooOO0OOO +ooOOo0OO +0ooOO0OOo +ooOO0Oo0 +ooOO0Oo +ooOO0OoO +ooOO0Ooo +ooOO0o00 +ooOO0o0 +ooOO0o0O +ooOO0o0o +ooOO0o +0ooOO0oO0 +ooOO0oO +ooOO0oOO +ooOO0oOo +ooOO0oo0 +ooOO0oo +ooOO0ooO +ooOO0ooo +ooOOO00 +ooOOoO +0ooOOO0 +ooOOO0O +ooOOO0o +ooOOO +ooOOOO00 +ooOOOO0 +ooOOOO0O +ooOOOO0o +ooOOOO +ooOOOOO0 +0ooOOOOO +ooOOOOOO +ooOOOOo +ooOOOo0 +ooOOOo +ooOOOoO +ooOOOoo +ooOOo000 +ooOOo00O +ooOOo00o +0ooOOo0O0 +ooOOo0O +ooOOo0Oo +ooOOo0o0 +ooOOo0o +ooOOo0oO +ooOOo0oo +ooOOo +ooOOoO0 +ooOOoO0O +0ooOOoO0o +ooOOoOo +ooOOoo00 +ooOOoo0 +ooOOoo0O +ooOOoo0o +ooOOoo +ooOOooO0 +ooOOooO +ooOOooOO +0ooOOooo0 +ooOOooo +ooOOoooo +ooOo0000 +ooOo000 +ooOo00 +ooOo00oO +ooOo00oo +ooOo0 +ooOo0O00 +00ooOo0o0 +0ooOo0O0 +0ooOo0oOo +0ooOo0O0O +0ooOo0O0o +0ooOo0O +0ooOo0OO0 +0ooOo0OO +0ooOoOo0o +0ooOooOOo +0ooOo0OOO +ooOo0OOo +ooOo0Oo0 +ooOo0Oo +ooOo0OoO +ooOo0Ooo +ooOo0o00 +ooOo0o0O +ooOo0o0o +ooOo0o +0ooOo0oO0 +ooOo0oO +ooOo0oOO +ooOo0oo0 +ooOo0oo +ooOo0ooO +ooOo0ooo +ooOoO000 +ooOoO00 +ooOoO00O +0ooOoO00o +ooOoO0 +ooOoO0O0 +ooOoO0O +ooOoO0OO +ooOoO0Oo +ooOoO0o0 +ooOoO0o +ooOoO0oO +ooOoO0oo +0ooOoO +ooOoOoOO +ooOoOO00 +ooOoOO0 +ooOoOOOo +ooOoOO0O +ooOoOO0o +ooOoOO +ooOoOOO0 +ooOoOOO +0ooOoOOOO +ooOoOOo0 +ooOoOOo +ooOoOOoO +ooOoOOoo +ooOoOo00 +ooOoOo0 +ooOoOo0O +ooOoOo +ooOoOoO0 +0ooOoOoO +ooOoOoOo +ooOoOoo0 +ooOoOoo +ooOoOooO +ooOoOooo +ooOoo000 +ooOoo00 +ooOooo0o +ooOoo00O +0ooOoo00o +ooOoo0 +ooOoo0O0 +ooOoo0O +ooOoo0OO +ooOoo0Oo +ooOoo0o0 +ooOoo0o +ooOoo0oo +ooOoo0oO +0ooooO +ooOoo +ooOooO00 +ooOooO0 +ooOooO0O +ooOooO0o +ooOooo +ooOooO +ooOooOO0 +ooOooOO +0ooOooOo0 +ooOooOo +ooOooOoO +ooOooOoo +ooOooo00 +ooOooo0 +ooOooo0O +ooOoooO0 +ooOoooO +ooOoooOO +000ooOoooOo +00ooOoooo0 +00ooOoooo +00ooOooooO +00ooOooooo +00ooo0000 +00ooo000oo +00ooo0000o +00ooo000 +00ooo000O +00ooo000OO +0ooo000Oo +0ooo000o +0ooo000oO +0ooo00 +0ooo00O00 +0ooo00oO0 +0ooo00O0O +0ooo00O0o +0ooo00O +00ooo00Oo0 +0ooo00OO0 +0ooo00OO +0ooo00OOO +0ooo00OOo +0ooo00Oo +0ooo00OoO +0ooo00Ooo +0ooo00o00 +0ooo00o0 +00ooo00o0O +0ooo00o0o +0ooo00o +0ooo00oO +0ooo00oOO +0ooo00oOo +0ooo00oo0 +0ooo00oo +0ooo00ooO +0ooo00ooo +00ooo0 +0ooo0O000 +0ooo0O00 +0ooo0O00O +0ooo0O00o +0ooo0oo +0ooo0o0 +0ooo0oO +0ooo0O0 +0ooo0O0O0 +00ooo0O0O +0ooo0O0OO +0ooo0O0Oo +0ooo0O0o0 +0ooo0O0o +0ooo0O0oO +0ooo0O +0ooo0OO00 +0ooo0OO0 +0ooo0OO0O +00ooo0OO0o +0ooo0Oo +0ooo0OO +0ooo0OOO0 +0ooo0OOO +0oooo00oo +0ooo0OOoO +0ooo0OOOO +0ooo0OOOo +0ooo0OOo0 +00ooo0OOoo +0ooo0Oo00 +0ooo0Oo0O +0ooo0Oo0o +0ooo0OoO0 +0ooo0OoOO +0ooo0OoOo +0ooo0Ooo0 +0ooo0OooO +0ooo0Oooo +00ooo0o000 +0ooo0o00 +0ooo0o00O +0ooo0o00o +0ooo0o0OO +0ooo0o0O0 +0ooo0o0O +0ooo0o0Oo +0ooo0o0o0 +0ooo0o0o +00ooo0o0oO +0ooo0o0oo +0ooo0oO00 +0ooo0oO0 +0ooo0oO0O +0ooo0oO0o +0ooo0oOO0 +0ooo0oOOO +0ooo0oOOo +0ooo0oOo0 +00ooo0oOoO +0ooo0oOoo +0ooo0oo00 +0ooo0oo0 +0ooo0oo0O +0ooo0oo0o +0ooo0ooO0 +0ooo0ooO +0ooo0ooOO +0ooo0ooOo +0ooo0ooo0 +ooo0oooo +oooO0oo0 +oooO0000 +oooO000 +oooO00o0 +oooO000O +oooO0ooo +oooO000o +ooooo0 +0oooooo +ooooOo +oooO00 +oooO00O0 +oooO00O +oooO00Oo +oooO00OO +oooO00o +ooooOOOo +ooooOOOO +0ooooOo00 +oooO0oO0 +oooO00oO +oooO00oo +oooO0 +oooO0O00 +oooO0O0 +oooO0O0O +oooO0O0o +oooO0O +0oooOOo0O +oooO0OO0 +oooO0OO +oooO0OOO +oooO0OOo +oooO0Oo0 +oooO0Oo +oooO0OoO +oooO0Ooo +oooO0o00 +0oooO0o0 +oooO0o0O +oooO0o0o +oooooO +oooO0o +oooO0oO +oooO0oo +oooO0ooO +oooO +oooOooOO +0oooOO000 +oooOO00 +oooOO0o0 +oooOO00O +oooOO00o +oooOO0O0 +oooOO0O +oooOO0OO +oooOO0Oo +oooOO0o +0oooOO0oO +oooOO0oo +oooOO +oooOOO00 +oooOOO0 +oooOOO0O +oooOOO0o +oooOOO +oooOOOO0 +oooOOOO +0oooOOOOO +oooOOOOo +oooOOOo0 +oooOOOo +oooOOOoO +oooOOOoo +oooOOo00 +oooOOo0 +oooOOo0o +oooOOo +0oooOOoO0 +oooOOoO +oooOOoOO +oooOOoOo +oooOOoo0 +oooOOoo +oooOOooO +oooOOooo +oooOo000 +oooOo00 +00oooOo00O +0oooOo00o +0oooOo0 +0oooOo0oo +0oooOo0O0 +0oooOo0O +0oooOo0OO +0oooOo0Oo +0oooOo0o0 +0oooOo0o +0oooOo0oO +oooOo +oooOoO00 +oooOoO0 +oooOoO0O +oooOoO0o +oooOoOOO +oooOoOO0 +oooOoOO +oooOoOOo +0oooOoOo0 +oooOoOo +oooOoOoO +oooOoOoo +oooOoo00 +oooOoo0 +oooOoo0O +oooOoo0o +oooOooO0 +oooOooOo +0oooOooo0 +oooOooo +oooOoooO +oooOoooo +oooo0000 +oooo000O +oooo000o +oooo00 +oooo00o0 +oooo00O0 +0oooo00O +oooo00OO +oooo00Oo +oooo00oO +oooo0 +oooo0O00 +oooo0O0 +oooo0O0O +oooo0O0o +oooo0O +0oooo0OO0 +oooo0OO +oooo0OOO +oooo0OOo +oooo0Oo0 +oooo0Oo +oooo0OoO +oooo0Ooo +oooo0o00 +oooo0o0 +0oooo0o0O +oooo0o0o +oooo0o +oooo0oO0 +oooo0oO +oooo0oOO +oooo0oOo +oooo0oo0 +oooo0oo +oooo0ooO +0oooo0ooo +oooo +ooooO00 +ooooOOoO +ooooO00O +ooooO00o +ooooO0 +ooooO0O +ooooO0OO +ooooO0Oo +0ooooO0o0 +ooooO0o +ooooO0oO +ooooOO0 +ooooOO0o +ooooOO +ooooOoo0 +ooooOOO0 +ooooOOO +ooooOOo +0ooooOo0 +ooooOo0O +ooooOo0o +ooooOoO0 +ooooOoO +ooooOoo +ooooOooO +ooooOooo +ooooo000 +ooooo00 +00ooooo00O +0ooooo00o +0ooooo0O0 +0ooooo0O +0ooooo0OO +0ooooo0Oo +0ooooo0o0 +0ooooo0o +0ooooo0oO +0ooooo0oo +0ooooo +oooooO00 +oooooO0 +oooooOo0 +oooooO0O +oooooO0o +oooooOO0 +oooooOO +oooooOOO +oooooOOo +0oooooOoO +oooooOoo +oooooo00 +oooooo0 +oooooo0O +oooooo0o +ooooooO0 +ooooooOO +ooooooOo +ooooooo0 +0oooooooO +oooooooo +O +O0 +O00 +O000 +O0000 +O00000 +O000000 +O0000000 +O000000O +O00000O +O00000O0 +O00000OO +O0000O +O0000O0 +O0000O00 +O0000O0O +O0000OO +O0000OO0 +O0000OOO +O000O +O000O0 +O000O00 +O000O000 +O000O00O +O000O0O +O000O0O0 +O000o0oO +O000Oo +O000OO0 +O000oo00 +O000OO0O +O000OOO +O000OOO0 +O000OOOO +O00O +O00O0 +O00O00 +O00O000 +O00O0000 +O00O000O +O00O00O +O00O00O0 +O00O00OO +O00O0O +O00O0O0 +O00O0O00 +O00O0O0O +O00O0oO +O00O0OO0 +O00O0OOO +O00OO +O00OO0 +O00OO00 +O00Oo000 +O00Oo00O +O00Oo0O +O00Oo0O0 +O00oo0oO +O00OOO +O00OOO0 +O00OoO00 +O00ooo0O +O00OOOO +O00oOoO0 +O00ooooO +O0O +O0O0 +O0O00 +O0O000 +O0O0000 +o0o00000 +o0o0000O +O0O000O +o0O000O0 +o0O000OO +O0O00O +O0O00O0 +o0O00O00 +o0O00O0O +O0O00oo +o0O00OO0 +o0O00OOo +O0o0o +O0O0O0 +O0O0O00 +o0O0O000 +o0O0O00o +O0O0O0O +o0O0O0O0 +o0O0O0OO +O0O0Oo +O0o0oo0 +o0O0OO00 +o0O0OO0o +O0o0ooo +o0O0OOo0 +o0O0OOOO +O0OO +O0OO0 +O0OO00 +O0OO000 +o0OO0000 +o0OO000O +o0Oo00O +o0OO00O0 +o0OO00oO +O0OO0o +O0OO0O0 +o0OO0O00 +o0oO0O0O +O0OO0OO +o0oO0Oo0 +o0oO0oOo +O0OOO +O0OOo0 +o0OoO00 +o0OOO000 +o0OoO00o +O0OoO0o +o0ooo0O0 +o0ooo0Oo +O0oOOO +O0OOOO0 +o0ooOO00 +o0OOOO0O +O0oOOOO +o0ooOOo0 +o0ooooOO +OO +OO0 +OO00 +OO000 +Oo0000 +OO00000 +oO000000 +oO00000O +OO0000O +oO0000O0 +oO0000OO +OO000O +OO000O0 +oO000O00 +oO000o0O +oO000OO +oO000OO0 +oo000ooo +OO00o +OO00o0 +OO00O00 +oO00O000 +oO00O00O +OO00O0O +oO00O0O0 +oO00O0OO +Oo00oO +OO00OO0 +oO00OO00 +oO00OO0o +Oo00oOo +oO00OOO0 +oO00OOOO +OO0O +OO0O0 +OO0O00 +OO0O000 +oO0O0000 +oO0O000O +OO0O00O +oO0O00O0 +oO0O00OO +OO0o0O +OO0O0O0 +oO0O0o00 +oo0o0O0O +Oo0o0OO +oO0O0OO0 +oO0O0Ooo +OO0Oo +OO0OO0 +OO0OO00 +oO0Oo000 +oO0Oo00o +OO0OO0O +oO0OO0O0 +oO0Oo0oO +Oo0OOO +OO0OOO0 +oO0OOo00 +oO0OoO0o +Oo0OoOO +oO0Oooo0 +oO0OoOOo +OOo +OOO0 +OoO00 +OOO000 +OOO0000 +oOo00000 +oOo0000o +OOO000O +oOo000O0 +oOo000oO +OOO00O +ooo00O0 +oOo00O00 +oOo00O0o +OOO00OO +oOO00oo0 +oOo00Ooo +OOo0O +OOO0O0 +OOO0O00 +oOO0o000 +oOO0o00O +Ooo0o0O +oOo0o0O0 +oOo0o0oo +OOO0OO +Ooo0Oo0 +oOO0OO00 +oOo0oo0o +ooo0ooo +oOO0OOO0 +oOo0oooo +OOOO +OooO0 +OOOO00 +OOOO000 +oOOO0000 +oOOO000O +ooOo00o +oOOO00O0 +oOOO00OO +OOOO0o +OOOO0O0 +oOOO0O00 +oOOO0O0O +Oooo0Oo +oOOO0Oo0 +oooO0oOo +Ooooo +OOoOO0 +OoOOO00 +ooOOO000 +ooOOO00o +OOOOO0O +oOOoO0o0 +ooOOO0OO +oooOoo +OOOOOO0 +ooOOoO00 +ooooOO0O +ooOOoOO +ooOOOOo0 +ooOOOoOO diff --git a/athena-all/logo.svg b/athena-all/logo.svg new file mode 100644 index 000000000..f54b7dcce --- /dev/null +++ b/athena-all/logo.svg @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/DynamicAction.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/DynamicAction.java similarity index 82% rename from athena-all/src/main/java/run/mone/m78/ip/action/DynamicAction.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/DynamicAction.java index 283b13576..8622d0415 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/action/DynamicAction.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/DynamicAction.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.action; +package com.xiaomi.youpin.tesla.ip.action; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -6,10 +6,10 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.common.PromptType; -import run.mone.m78.ip.service.PromptService; -import run.mone.m78.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.service.PromptService; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/GenerateAction.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/GenerateAction.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/action/GenerateAction.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/GenerateAction.java index 519255ab6..59aa76568 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/action/GenerateAction.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/GenerateAction.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.action; +package com.xiaomi.youpin.tesla.ip.action; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -53,7 +53,7 @@ private void build(String filePath, String fileName) { } try { - Files.write(Paths.get(filePath + File.separator + fileName), "".getBytes()); + Files.write(Paths.get(filePath + File.separator + fileName), "abc--->zzy".getBytes()); } catch (IOException e) { e.printStackTrace(); } diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/MenuActionGroup.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/MenuActionGroup.java new file mode 100644 index 000000000..f8ff8ea70 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/MenuActionGroup.java @@ -0,0 +1,47 @@ +package com.xiaomi.youpin.tesla.ip.action; + +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.Tag; +import com.xiaomi.youpin.tesla.ip.common.ConfigCenter; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * @author caobaoyu + * @author goodjava@qq.com + * @description: + * @date 2023-06-14 14:15 + */ +public class MenuActionGroup extends ActionGroup { + + public MenuActionGroup() { + super("Prompt", true); + } + + @Override + public AnAction @NotNull [] getChildren(AnActionEvent e) { + if (ResourceUtils.checkDisableCodeCompletionStatus() || LabelUtils.getLabelValue(e.getProject(), Const.DISABLE_ACTION_GROUP, "false").equals("true")) { + return new AnAction[]{}; + } +// Map menuTag = ConfigCenter.getMenuTag(); +// Map> tagPromptInfo = new LinkedHashMap<>(); +// tagPromptInfo.put("Collection", Prompt.getCollected()); +// menuTag.keySet().forEach(tag -> tagPromptInfo.put(tag, Prompt.getPromptInfoByTag(tag))); +// List actions = tagPromptInfo.entrySet().stream().map((entry) -> new MenuAction(entry.getKey(), entry.getValue())).toList(); +// return actions.toArray(new AnAction[0]); + //第一个版本之显示系统级别的了 + List list = Prompt.getPromptInfoByTag("system"); + list.addAll(Prompt.getCollected()); + return list.stream().map(it -> new DynamicAction(it.getDesc(), Prompt.getPromptType(it), it)).toArray(AnAction[]::new); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/NaviAction.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/NaviAction.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/action/NaviAction.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/NaviAction.java index 654325c43..9b897fc48 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/action/NaviAction.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/NaviAction.java @@ -14,13 +14,14 @@ * limitations under the License. */ -package run.mone.m78.ip.action; +package com.xiaomi.youpin.tesla.ip.action; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; -import run.mone.m78.ip.component.NaviComponent; +import com.xiaomi.youpin.tesla.ip.component.ChatComponent; +import com.xiaomi.youpin.tesla.ip.component.NaviComponent; import org.jetbrains.annotations.NotNull; /** diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/PluginAction.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/PluginAction.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/action/PluginAction.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/PluginAction.java index d3487a43c..ad59675f1 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/action/PluginAction.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/PluginAction.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package run.mone.m78.ip.action; +package com.xiaomi.youpin.tesla.ip.action; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; -import run.mone.m78.ip.component.PluginComponent; +import com.xiaomi.youpin.tesla.ip.component.PluginComponent; import org.jetbrains.annotations.NotNull; /** diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/UltramanAction.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/UltramanAction.java similarity index 97% rename from athena-all/src/main/java/run/mone/m78/ip/action/UltramanAction.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/UltramanAction.java index 483aab16b..10341faeb 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/action/UltramanAction.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/action/UltramanAction.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.action; +package com.xiaomi.youpin.tesla.ip.action; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Action.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Action.java new file mode 100644 index 000000000..06c76dd02 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Action.java @@ -0,0 +1,50 @@ +package com.xiaomi.youpin.tesla.ip.bo; + +public enum Action { + + CHAT(1, "chat"), + GENERATE_CODE(2, "generate_code"), + CODE_SUGGESTION(3, "code_suggestion"), + GENERATE_COMMENT(4, "generate_comment"), + SMART_NAMING(5, "smart_naming"), + GIT_PUSH(6, "git_push"), + UNIT_TEST(7, "unit_test"), + BUG_FIX(8, "bug_fix"), + INSERT_CODE_FROM_CHAT(9, "insert_code_from_chat"), + INLAY(10, "inlay"); + + private final int code; + private final String name; + + Action(int code, String name) { + this.code = code; + this.name = name; + } + + public int getCode() { + return code; + } + + public String getName() { + return name; + } + + public static Action fromCode(int code) { + for (Action action : Action.values()) { + if (action.getCode() == code) { + return action; + } + } + throw new IllegalArgumentException("Invalid code: " + code); + } + + public static Action fromName(String name) { + for (Action action : Action.values()) { + if (action.getName().equalsIgnoreCase(name)) { + return action; + } + } + throw new IllegalArgumentException("Invalid name: " + name); + } +} + diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AddMethodConfig.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AddMethodConfig.java similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/bo/AddMethodConfig.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AddMethodConfig.java index 61bdbc5d0..c89f7c06f 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/AddMethodConfig.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AddMethodConfig.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import com.intellij.psi.PsiType; import lombok.Builder; @@ -20,4 +20,5 @@ public class AddMethodConfig implements Serializable { private boolean isInterface; + } diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AiCodePromptRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiCodePromptRes.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/bo/AiCodePromptRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiCodePromptRes.java index c3e1de3d7..d76a24a11 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/AiCodePromptRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiCodePromptRes.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AiCodeRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiCodeRes.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/bo/AiCodeRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiCodeRes.java index 7c64059c0..2978a8671 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/AiCodeRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiCodeRes.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AiMessage.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiMessage.java similarity index 91% rename from athena-all/src/main/java/run/mone/m78/ip/bo/AiMessage.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiMessage.java index 050435e5c..c971bc357 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/AiMessage.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiMessage.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AiMessageType.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiMessageType.java similarity index 78% rename from athena-all/src/main/java/run/mone/m78/ip/bo/AiMessageType.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiMessageType.java index 5ff0bcc3c..fccd87415 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/AiMessageType.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AiMessageType.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AnnoInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AnnoInfo.java similarity index 84% rename from athena-all/src/main/java/run/mone/m78/ip/bo/AnnoInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AnnoInfo.java index 9cf904924..d90b51641 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/AnnoInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AnnoInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AnnoMember.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AnnoMember.java similarity index 83% rename from athena-all/src/main/java/run/mone/m78/ip/bo/AnnoMember.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AnnoMember.java index e1a02d7a5..cf000eea3 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/AnnoMember.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AnnoMember.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AthenaReq.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AthenaReq.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/bo/AthenaReq.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AthenaReq.java index be765e312..351aaf7fa 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/AthenaReq.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AthenaReq.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/AudioRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AudioRes.java similarity index 78% rename from athena-all/src/main/java/run/mone/m78/ip/bo/AudioRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AudioRes.java index abc345e40..a99a8d596 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/AudioRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/AudioRes.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ClassInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ClassInfo.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ClassInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ClassInfo.java index 1c16cee3b..0096ae6ec 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ClassInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ClassInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Builder; import lombok.Data; @@ -15,6 +15,8 @@ public class ClassInfo implements Serializable, PsiInfo { private String className; + private String simpleName; + private String moduleName; private boolean hidden; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassMeta.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/CreateClassMeta.java similarity index 63% rename from athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassMeta.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/CreateClassMeta.java index de39c8395..518bac980 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassMeta.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/CreateClassMeta.java @@ -1,8 +1,10 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; +import com.xiaomi.youpin.tesla.ip.bo.prompt.PromptParam; import lombok.Data; import java.io.Serializable; +import java.util.List; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/CreateClassRes.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/CreateClassRes.java index 0bd217344..e2ba850d0 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/CreateClassRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/CreateClassRes.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Dependency.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Dependency.java similarity index 84% rename from athena-all/src/main/java/run/mone/m78/ip/bo/Dependency.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Dependency.java index 2f1434d62..bd4e6d464 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/Dependency.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Dependency.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ElementInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ElementInfo.java similarity index 85% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ElementInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ElementInfo.java index 7eeb9418b..2f69c2ac5 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ElementInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ElementInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/FieldInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/FieldInfo.java similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/bo/FieldInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/FieldInfo.java index 76d9c10b4..3a975eab0 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/FieldInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/FieldInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/GenerateCodeReq.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/GenerateCodeReq.java similarity index 67% rename from athena-all/src/main/java/run/mone/m78/ip/bo/GenerateCodeReq.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/GenerateCodeReq.java index 7111cfaad..ed5ae042c 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/GenerateCodeReq.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/GenerateCodeReq.java @@ -1,12 +1,14 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.common.PromptType; +import com.intellij.psi.PsiMethod; +import com.xiaomi.youpin.tesla.ip.common.PromptType; import lombok.Builder; import lombok.Data; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; @@ -16,7 +18,7 @@ * @author zhangzhiyong * @description: * @date 2023-05-17 16:53 - * + *

* 主要用来生成代码 */ @Data @@ -52,7 +54,11 @@ public class GenerateCodeReq { private String showDialog; - private Map param; + @Builder.Default + private Map param = new HashMap<>(); + + @Builder.Default + private Map objMap = new HashMap<>(); /** * 格式化代码 @@ -82,6 +88,9 @@ public class GenerateCodeReq { //class相关代码 private String classCode; + //class代码,且带着占位标记($$这里需要补全代码$$) + private String classCodeWithMark; + private String qualifiedName; private String className; @@ -94,9 +103,17 @@ public class GenerateCodeReq { //选中的方法code(鼠标停留的位置) private String methodCode; + //带行号的method + private String lineNumberedMethod; + + private PsiMethod psiMethod; + //选中的内容 private String selectText; + //当前行内容 + private String currentLine; + //操作系统名称 private String systemName; @@ -107,5 +124,19 @@ public class GenerateCodeReq { @Builder.Default private String taskType = "edit"; + //编辑器中的偏移量 + private int offset; + + private List inheritedMethods; + + //用户设定的scope + private String userSettingScope; + + //debug的错误信息 + private String debugErrorMessage; + + //用来阻塞用的 + private CountDownLatch countDownLatch; + } diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/IdeaPluginInfoBo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/IdeaPluginInfoBo.java similarity index 98% rename from athena-all/src/main/java/run/mone/m78/ip/bo/IdeaPluginInfoBo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/IdeaPluginInfoBo.java index 99061caa0..aad726f2e 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/IdeaPluginInfoBo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/IdeaPluginInfoBo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/LombokTest.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/LombokTest.java similarity index 77% rename from athena-all/src/main/java/run/mone/m78/ip/bo/LombokTest.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/LombokTest.java index c6591f5c5..e9b5906f1 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/LombokTest.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/LombokTest.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/M78CodeGenerationInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/M78CodeGenerationInfo.java new file mode 100644 index 000000000..930227cee --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/M78CodeGenerationInfo.java @@ -0,0 +1,71 @@ +package com.xiaomi.youpin.tesla.ip.bo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 实体类。 + * + * @author zhangzhiyong + * @since 2024-06-12 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class M78CodeGenerationInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + private Integer id; + + private Long ctime; + + private Long utime; + + private Integer state; + + private String projectName; + + private String className; + + private Integer codeLinesCount; + + private String methodName; + + private String username; + + /** + * 1 根据注释生成代码 + * 2 inlay代码提示 + */ + @Builder.Default + private int type = 1; + + private String annotation; + + /** + * 1 idea + * 2 vscode + */ + @Builder.Default + private int source = 1; + + private String pluginVersion; + + private String ip; + + private String systemVersion; + + /** + * 操作类型 (1聊天 2生成代码 3代码建议 4生成注释 5智能命名 6一键push 7单元测试 8bug_fix) + */ + @Builder.Default + private int action = 2; + + private String ideVersion; +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Message.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Message.java similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/bo/Message.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Message.java index 52d2ce9ef..067d834fe 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/Message.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Message.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/MessageConsumer.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/MessageConsumer.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/bo/MessageConsumer.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/MessageConsumer.java index 1797467fa..5fbaa1fb4 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/MessageConsumer.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/MessageConsumer.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/MethodInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/MethodInfo.java similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/bo/MethodInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/MethodInfo.java index 19068e47d..5ac86c0e6 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/MethodInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/MethodInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import java.io.Serializable; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ModelRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ModelRes.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ModelRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ModelRes.java index 78d05d655..959ebb7e7 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ModelRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ModelRes.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ModuleInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ModuleInfo.java similarity index 93% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ModuleInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ModuleInfo.java index dd9b80fd0..2a63e2fc9 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ModuleInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ModuleInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Builder; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Msg.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Msg.java similarity index 84% rename from athena-all/src/main/java/run/mone/m78/ip/bo/Msg.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Msg.java index 8c3f5e735..bc5e70d58 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/Msg.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Msg.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ParamDialogReq.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ParamDialogReq.java similarity index 85% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ParamDialogReq.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ParamDialogReq.java index eae8cb370..e5218e710 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ParamDialogReq.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ParamDialogReq.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ParamInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ParamInfo.java similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ParamInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ParamInfo.java index 92430e8c1..9ea67a34c 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ParamInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ParamInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import com.intellij.psi.PsiType; import lombok.Builder; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/PluginDeleteParam.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PluginDeleteParam.java similarity index 98% rename from athena-all/src/main/java/run/mone/m78/ip/bo/PluginDeleteParam.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PluginDeleteParam.java index a08d374ee..5022a51bd 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/PluginDeleteParam.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PluginDeleteParam.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import java.util.List; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ProjectModuleInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ProjectModuleInfo.java similarity index 85% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ProjectModuleInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ProjectModuleInfo.java index 0d6118d84..8d3b6ab29 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ProjectModuleInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ProjectModuleInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/PromptContext.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PromptContext.java similarity index 85% rename from athena-all/src/main/java/run/mone/m78/ip/bo/PromptContext.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PromptContext.java index 5e2b7c875..9932a73d4 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/PromptContext.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PromptContext.java @@ -1,9 +1,10 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import com.intellij.openapi.editor.Editor; import lombok.Data; import run.mone.ultraman.bo.AthenaFieldInfo; import run.mone.ultraman.bo.AthenaMethodInfo; +import run.mone.ultraman.bo.PoClassInfo; import java.io.Serializable; import java.util.List; @@ -29,6 +30,8 @@ public class PromptContext implements Serializable { private List resourceCode; + private List poClassInfos; + private List methodCodeList; private List fieldCodeList; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/PromptInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PromptInfo.java similarity index 69% rename from athena-all/src/main/java/run/mone/m78/ip/bo/PromptInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PromptInfo.java index d99b9137b..c452e98be 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/PromptInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PromptInfo.java @@ -1,7 +1,9 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.List; @@ -15,6 +17,8 @@ */ @Data @Builder +@AllArgsConstructor +@NoArgsConstructor public class PromptInfo implements Serializable { private Long id; @@ -47,6 +51,18 @@ public boolean open(String key) { return this.labels.getOrDefault(key, "false").equals("true"); } + public boolean has(String key) { + return this.labels.containsKey(key); + } + + public boolean open(String key, String defaultValue) { + return this.labels.getOrDefault(key, defaultValue).equals("true"); + } + + public String getLabelValue(String key, String defaultValue) { + return this.labels.getOrDefault(key, defaultValue); + } + @Override public boolean equals(Object o) { diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ProxyAsk.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ProxyAsk.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ProxyAsk.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ProxyAsk.java index 462581438..a04f9f900 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ProxyAsk.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ProxyAsk.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/PsiInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PsiInfo.java similarity index 84% rename from athena-all/src/main/java/run/mone/m78/ip/bo/PsiInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PsiInfo.java index fb1d621e9..465648021 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/PsiInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/PsiInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Req.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Req.java similarity index 87% rename from athena-all/src/main/java/run/mone/m78/ip/bo/Req.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Req.java index 2fbcd8824..737a0cb52 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/Req.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Req.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Response.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Response.java similarity index 98% rename from athena-all/src/main/java/run/mone/m78/ip/bo/Response.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Response.java index 950bd559e..5c4d9e3f7 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/Response.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Response.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import java.io.Serializable; import java.util.Map; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Result.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Result.java similarity index 97% rename from athena-all/src/main/java/run/mone/m78/ip/bo/Result.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Result.java index 1d631876d..47424f477 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/Result.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Result.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/RobotContext.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/RobotContext.java similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/bo/RobotContext.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/RobotContext.java index 58dc6a661..ade15fe05 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/RobotContext.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/RobotContext.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/RobotReq.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/RobotReq.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/bo/RobotReq.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/RobotReq.java index 14dec27cc..567a73380 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/RobotReq.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/RobotReq.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import com.intellij.openapi.project.Project; import lombok.Builder; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ServerInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ServerInfo.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ServerInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ServerInfo.java index c3e977c70..4b2c5cb0f 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ServerInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ServerInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/SpiderUrl.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/SpiderUrl.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/bo/SpiderUrl.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/SpiderUrl.java index 5a4e9ec77..5052e9b5b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/SpiderUrl.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/SpiderUrl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; /** * @Author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/Tag.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Tag.java similarity index 58% rename from athena-all/src/main/java/run/mone/m78/ip/bo/Tag.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Tag.java index 112fa75c5..c004a7af9 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/Tag.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/Tag.java @@ -1,6 +1,9 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; import java.io.Serializable; @@ -9,6 +12,9 @@ * @date 2023/5/27 14:45 */ @Data +@Builder +@NoArgsConstructor +@AllArgsConstructor public class Tag implements Serializable { diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/TbTask.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/TbTask.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/bo/TbTask.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/TbTask.java index 00fd02585..99f0adc40 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/TbTask.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/TbTask.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; /** * @Author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/TeslaPluginConfig.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/TeslaPluginConfig.java similarity index 81% rename from athena-all/src/main/java/run/mone/m78/ip/bo/TeslaPluginConfig.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/TeslaPluginConfig.java index a3f8f12b6..f7ca9bc1d 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/TeslaPluginConfig.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/TeslaPluginConfig.java @@ -14,14 +14,17 @@ * limitations under the License. */ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; +import com.xiaomi.youpin.tesla.ip.common.Const; import lombok.Data; +import run.mone.ultraman.listener.bo.CompletionEnum; import java.io.Serializable; import java.util.List; + /** * @author goodjava@qq.com */ @@ -54,10 +57,18 @@ public class TeslaPluginConfig implements Serializable { private String zToken = ""; + // chat的model private String model = ""; + // 非chat的model + private String noChatModel = ""; + + private String shortcut = ""; + private List modelList; + private CompletionEnum completionMode = CompletionEnum.SINGLE_LINE; + public String getMvnPath() { return mvnPath; @@ -154,4 +165,19 @@ public String getzToken() { public void setzToken(String zToken) { this.zToken = zToken; } + + public CompletionEnum getCompletionMode() { + return completionMode; + } + + public void setCompletionMode(CompletionEnum completionMode) { + this.completionMode = completionMode; + } + + public void setModelList(List modelList) { + if(modelList != null && !modelList.contains(Const.USE_BOT_MODEL)){ + modelList.add(Const.USE_BOT_MODEL); + } + this.modelList = modelList; + } } diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/UserBo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/UserBo.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/bo/UserBo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/UserBo.java index fe74ac60c..8ea284e93 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/UserBo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/UserBo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; /** * @Author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/UserVo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/UserVo.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/bo/UserVo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/UserVo.java index 8d6f4c315..b33884c98 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/UserVo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/UserVo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; /** diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ValueInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ValueInfo.java similarity index 83% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ValueInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ValueInfo.java index ef6103387..9ef8c4c17 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ValueInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ValueInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ZAddrRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZAddrRes.java similarity index 83% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ZAddrRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZAddrRes.java index 989c4e107..f8a31e3f3 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ZAddrRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZAddrRes.java @@ -1,8 +1,9 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; import java.util.List; +import java.util.Map; /** * @author caobaoyu @@ -30,5 +31,5 @@ public class ZAddrRes { private List modelsV2; - + private String userName; } diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ZAskParam.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZAskParam.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ZAskParam.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZAskParam.java index e57c98bad..dc8fd03a9 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ZAskParam.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZAskParam.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptAddonItem.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZPromptAddonItem.java similarity index 82% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptAddonItem.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZPromptAddonItem.java index 30ee19001..c40f87662 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptAddonItem.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZPromptAddonItem.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZPromptRes.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZPromptRes.java index 6cea10b4d..f2dff338a 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ZPromptRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZPromptRes.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/ZRequestPram.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZRequestPram.java similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/bo/ZRequestPram.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZRequestPram.java index 355b54c0c..71c5977f1 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/ZRequestPram.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/ZRequestPram.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo; +package com.xiaomi.youpin.tesla.ip.bo; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Choice.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Choice.java similarity index 75% rename from athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Choice.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Choice.java index 65bd71770..bd9b779fa 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Choice.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Choice.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.chatgpt; +package com.xiaomi.youpin.tesla.ip.bo.chatgpt; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Completions.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Completions.java similarity index 87% rename from athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Completions.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Completions.java index 1768aa682..222254ed0 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Completions.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Completions.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.chatgpt; +package com.xiaomi.youpin.tesla.ip.bo.chatgpt; import lombok.Builder; import lombok.Data; @@ -16,7 +16,7 @@ public class Completions implements Serializable { @Builder.Default - private String model = "gpt-4-1106-preview"; + private String model = "gpt4_o"; private List messages; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Format.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Format.java similarity index 81% rename from athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Format.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Format.java index b6a216f6c..687676bbb 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Format.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Format.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.chatgpt; +package com.xiaomi.youpin.tesla.ip.bo.chatgpt; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ImageUrl.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/ImageUrl.java similarity index 78% rename from athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ImageUrl.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/ImageUrl.java index ddcff8ea7..65d631118 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ImageUrl.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/ImageUrl.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.chatgpt; +package com.xiaomi.youpin.tesla.ip.bo.chatgpt; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/LocalReq.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/LocalReq.java similarity index 83% rename from athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/LocalReq.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/LocalReq.java index 04565ea2f..df8783935 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/LocalReq.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/LocalReq.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.chatgpt; +package com.xiaomi.youpin.tesla.ip.bo.chatgpt; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Message.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Message.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Message.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Message.java index ffcd848ba..a12c9da6a 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/Message.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/Message.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.chatgpt; +package com.xiaomi.youpin.tesla.ip.bo.chatgpt; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqContent.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/ReqContent.java similarity index 84% rename from athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqContent.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/ReqContent.java index 9c6e3e9ca..a24ab007a 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqContent.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/ReqContent.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.chatgpt; +package com.xiaomi.youpin.tesla.ip.bo.chatgpt; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqMessage.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/ReqMessage.java similarity index 85% rename from athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqMessage.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/ReqMessage.java index 05d5720a8..161dce7b3 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/ReqMessage.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/ReqMessage.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.chatgpt; +package com.xiaomi.youpin.tesla.ip.bo.chatgpt; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/SpeechReq.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/SpeechReq.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/SpeechReq.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/SpeechReq.java index d3ce03d8d..fa4fe0cdd 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/SpeechReq.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/SpeechReq.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.chatgpt; +package com.xiaomi.youpin.tesla.ip.bo.chatgpt; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionReq.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/VisionReq.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionReq.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/VisionReq.java index f4418b7b1..572cbf6dc 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionReq.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/VisionReq.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.chatgpt; +package com.xiaomi.youpin.tesla.ip.bo.chatgpt; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/VisionRes.java similarity index 78% rename from athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/VisionRes.java index 92533e03e..ad18dd8bc 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/chatgpt/VisionRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/chatgpt/VisionRes.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.chatgpt; +package com.xiaomi.youpin.tesla.ip.bo.chatgpt; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParam.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/prompt/PromptParam.java similarity index 82% rename from athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParam.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/prompt/PromptParam.java index ccd82c65f..2411e9cbe 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParam.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/prompt/PromptParam.java @@ -1,12 +1,12 @@ -package run.mone.m78.ip.bo.prompt; +package com.xiaomi.youpin.tesla.ip.bo.prompt; import com.google.common.collect.Lists; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.util.ProjectUtils; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.common.Const; -import run.mone.m78.ip.util.LabelUtils; -import run.mone.m78.ip.util.PackageUtils; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.util.PackageUtils; +import com.xiaomi.youpin.tesla.ip.util.ProjectUtils; import lombok.Data; import java.io.Serializable; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParamType.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/prompt/PromptParamType.java similarity index 80% rename from athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParamType.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/prompt/PromptParamType.java index 36b0737dc..19e333bb5 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/prompt/PromptParamType.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/prompt/PromptParamType.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.prompt; +package com.xiaomi.youpin.tesla.ip.bo.prompt; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiChatMessage.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/AiChatMessage.java similarity index 97% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiChatMessage.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/AiChatMessage.java index bc012147c..1f4d082a6 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiChatMessage.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/AiChatMessage.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiMessageManager.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/AiMessageManager.java similarity index 99% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiMessageManager.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/AiMessageManager.java index c4f3f0d61..5f476ceca 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/AiMessageManager.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/AiMessageManager.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; import com.google.common.collect.Maps; import org.apache.commons.lang3.StringUtils; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/BoolData.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/BoolData.java similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/BoolData.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/BoolData.java index 8087d46a9..877712dd6 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/BoolData.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/BoolData.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/EventRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/EventRes.java similarity index 87% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/EventRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/EventRes.java index 6e5ae359b..00bef7748 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/EventRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/EventRes.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/ItemData.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/ItemData.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/ItemData.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/ItemData.java index c056e7483..a3ffe0fc4 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/ItemData.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/ItemData.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapData.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MapData.java similarity index 91% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapData.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MapData.java index 035e004bf..0e34219fd 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapData.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MapData.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapDataValue.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MapDataValue.java similarity index 84% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapDataValue.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MapDataValue.java index 67fa89c32..1ea802412 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MapDataValue.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MapDataValue.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; import lombok.Builder; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageData.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageData.java similarity index 67% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageData.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageData.java index 5ea160dca..8cced2eb9 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageData.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageData.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageReq.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageReq.java similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageReq.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageReq.java index bda2f4876..320b693ea 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageReq.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageReq.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageRes.java similarity index 87% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageRes.java index f90f2e108..5c3d0755b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageRes.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageType.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageType.java similarity index 86% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageType.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageType.java index 551f51061..9bc10bf1d 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/MessageType.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/MessageType.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/ProjectAiMessageManager.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/ProjectAiMessageManager.java similarity index 98% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/ProjectAiMessageManager.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/ProjectAiMessageManager.java index 3f5165a7b..1532572f4 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/ProjectAiMessageManager.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/ProjectAiMessageManager.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; import com.google.gson.Gson; import com.intellij.openapi.project.Project; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/Role.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/Role.java similarity index 72% rename from athena-all/src/main/java/run/mone/m78/ip/bo/robot/Role.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/Role.java index ff1a019af..f53e26e89 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/robot/Role.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/robot/Role.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.robot; +package com.xiaomi.youpin.tesla.ip.bo.robot; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/z/EmbeddingStatus.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/z/EmbeddingStatus.java similarity index 83% rename from athena-all/src/main/java/run/mone/m78/ip/bo/z/EmbeddingStatus.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/z/EmbeddingStatus.java index 975a3f9f2..c8fd20687 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/z/EmbeddingStatus.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/z/EmbeddingStatus.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.z; +package com.xiaomi.youpin.tesla.ip.bo.z; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/z/ZKnowledgeRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/z/ZKnowledgeRes.java similarity index 87% rename from athena-all/src/main/java/run/mone/m78/ip/bo/z/ZKnowledgeRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/z/ZKnowledgeRes.java index 052619481..1ca1d3d6d 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/z/ZKnowledgeRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/z/ZKnowledgeRes.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.z; +package com.xiaomi.youpin.tesla.ip.bo.z; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/bo/z/ZResult.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/z/ZResult.java similarity index 82% rename from athena-all/src/main/java/run/mone/m78/ip/bo/z/ZResult.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/z/ZResult.java index 3c7695802..f4553483f 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/bo/z/ZResult.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/bo/z/ZResult.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.bo.z; +package com.xiaomi.youpin.tesla.ip.bo.z; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/client/MyHttpClient.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/client/MyHttpClient.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/client/MyHttpClient.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/client/MyHttpClient.java index 92798ca90..ed2bdc815 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/client/MyHttpClient.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/client/MyHttpClient.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.client; +package com.xiaomi.youpin.tesla.ip.client; import okhttp3.OkHttpClient; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ApiCall.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ApiCall.java similarity index 80% rename from athena-all/src/main/java/run/mone/m78/ip/common/ApiCall.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ApiCall.java index a2c78c041..36d901864 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/ApiCall.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ApiCall.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.google.gson.Gson; @@ -28,7 +28,7 @@ */ public class ApiCall { - private static final String END_POINT = ""; + private static final String END_POINT = "http://127.0.0.1:8999"; public static final String MUSIC_API = END_POINT + "/music"; public static final String TEXT_API = END_POINT + "/text"; @@ -66,4 +66,14 @@ public String callIt(String url, String name) { } + public static void main(String[] args) { + ApiCall call = new ApiCall(); + //System.out.println(list); + + Map m = new HashMap<>(); + m.put("name", "zzy"); + m.put("cmd", "get"); + String res = call.postCall(CODE_API, new Gson().toJson(m)); + System.out.println(res); + } } diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ApiRes.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ApiRes.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/common/ApiRes.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ApiRes.java index 85b794b3e..1152c151a 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/ApiRes.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ApiRes.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import java.io.Serializable; import java.util.List; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/AthenaBiConsumer.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/AthenaBiConsumer.java similarity index 87% rename from athena-all/src/main/java/run/mone/m78/ip/common/AthenaBiConsumer.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/AthenaBiConsumer.java index ddac9950d..3f3eb8b67 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/AthenaBiConsumer.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/AthenaBiConsumer.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.intellij.openapi.project.Project; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/AthenaMessageConsumer.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/AthenaMessageConsumer.java similarity index 86% rename from athena-all/src/main/java/run/mone/m78/ip/common/AthenaMessageConsumer.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/AthenaMessageConsumer.java index fad04c126..e1c9511f6 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/AthenaMessageConsumer.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/AthenaMessageConsumer.java @@ -1,8 +1,8 @@ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.google.gson.Gson; -import run.mone.m78.ip.bo.AiMessage; -import run.mone.m78.ip.bo.MessageConsumer; +import com.xiaomi.youpin.tesla.ip.bo.AiMessage; +import com.xiaomi.youpin.tesla.ip.bo.MessageConsumer; import lombok.extern.slf4j.Slf4j; /** diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Base64Utils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Base64Utils.java new file mode 100644 index 000000000..398e259d9 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Base64Utils.java @@ -0,0 +1,16 @@ +package com.xiaomi.youpin.tesla.ip.common; + +import java.nio.charset.Charset; +import java.util.Base64; + +/** + * @author goodjava@qq.com + * @date 2024/6/19 08:47 + */ +public class Base64Utils { + + public static String decodeBase64String(String str) { + return new String(Base64.getDecoder().decode(str.getBytes(Charset.forName("utf8"))), Charset.forName("utf8")); + } + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ChromeUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ChromeUtils.java new file mode 100644 index 000000000..ed1562ab2 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ChromeUtils.java @@ -0,0 +1,59 @@ +package com.xiaomi.youpin.tesla.ip.common; + +import com.google.common.net.UrlEscapers; +import com.google.gson.Gson; +import com.intellij.ui.jcef.JBCefBrowser; +import com.xiaomi.youpin.tesla.ip.bo.Req; +import com.xiaomi.youpin.tesla.ip.bo.robot.AiChatMessage; +import com.xiaomi.youpin.tesla.ip.listener.UltrmanTreeKeyAdapter; +import lombok.SneakyThrows; + +/** + * @author goodjava@qq.com + * @date 2023/6/2 16:44 + */ +public class ChromeUtils { + + private static final Gson gson = new Gson(); + + @SneakyThrows + public static void call(String projectName, String method, String param, boolean useReq) { + if (useReq) { + param = UrlEscapers.urlFragmentEscaper().escape(gson.toJson(Req.builder().code(500).message(param))); + } else { + param = UrlEscapers.urlFragmentEscaper().escape(param); + } + JBCefBrowser jbCefBrowser = UltrmanTreeKeyAdapter.browserMap.get(projectName); + if (null != jbCefBrowser) { + jbCefBrowser.getCefBrowser().executeJavaScript(method + "('" + param + "');", jbCefBrowser.getCefBrowser().getURL(), 1); + } + } + + + public static void call(String projectName, String param, int code) { + call(projectName, param, "", code); + } + + public static void call(String projectName, String param, String sound, int code) { + param = UrlEscapers.urlFragmentEscaper().escape(gson.toJson(Req.builder().code(code).message(param).sound(sound))); + JBCefBrowser jbCefBrowser = UltrmanTreeKeyAdapter.browserMap.get(projectName); + if (null != jbCefBrowser) { + jbCefBrowser.getCefBrowser().executeJavaScript("showErrorCode" + "('" + param + "');", jbCefBrowser.getCefBrowser().getURL(), 1); + } + } + + public static void call(String projectName, AiChatMessage res) { + String param = UrlEscapers.urlFragmentEscaper().escape(gson.toJson(res)); + JBCefBrowser jbCefBrowser = UltrmanTreeKeyAdapter.browserMap.get(projectName); + if (null != jbCefBrowser) { + jbCefBrowser.getCefBrowser().executeJavaScript("showErrorCode" + "('" + param + "');", jbCefBrowser.getCefBrowser().getURL(), 1); + } + } + + + public static void call(String projectName, String method, String param) { + call(projectName, method, param, false); + } + + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ConfigCenter.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ConfigCenter.java new file mode 100644 index 000000000..74b437474 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ConfigCenter.java @@ -0,0 +1,71 @@ +package com.xiaomi.youpin.tesla.ip.common; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.xiaomi.youpin.tesla.ip.bo.AiCodeRes; +import com.xiaomi.youpin.tesla.ip.bo.Tag; +import com.xiaomi.youpin.tesla.ip.bo.ZPromptRes; +import com.xiaomi.youpin.tesla.ip.bo.ZRequestPram; +import lombok.Data; +import lombok.Getter; +import run.mone.ultraman.http.HttpClient; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author caobaoyu + * @description: 从Z获取一些基础配置 对应 -> 68 Athena の cfg center + * @date 2023-05-30 11:02 + */ +@Data +public class ConfigCenter { + + + private static Map copyrightingMap = new HashMap<>(); + + @Getter + private static List guide = new ArrayList<>(); + + private static List menuTag = new ArrayList<>(); + + public static Map getMenuTag() { + return menuTag.stream().collect(Collectors.toMap(Tag::getName, Function.identity())); + } + + public static void init(String zAddr) { + guide.clear(); + menuTag.clear(); + buildCopyrighting(zAddr); + } + + private static void buildCopyrighting(String zAddr) { + Safe.run(() -> { + ZRequestPram param = ZRequestPram.builder().token(ConfigUtils.getConfig().getzToken()).type(68).build(); + String url = zAddr + "/list"; + Gson gson = new Gson(); + String httpRes = HttpClient.callZServer(url, "copyrighting", gson.toJson(param)); + List data = gson.fromJson(httpRes, new TypeToken>() { + }.getType()); + Map collect = data.stream().collect(Collectors.toMap(ZPromptRes::getName, Function.identity())); + List> res = gson.fromJson(collect.get("copyrighting").getMeta(), new TypeToken>>() { + }.getType()); + res.forEach(l -> copyrightingMap.putAll(l)); + guide.addAll(gson.fromJson(collect.get("guide").getData(), new TypeToken>() { + }.getType())); + menuTag.addAll(gson.fromJson(collect.get("menu").getData(), new TypeToken>() { + }.getType())); + }); + + } + + public static AiCodeRes build(String type) { + return copyrightingMap.get(type); + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ConfigUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ConfigUtils.java similarity index 60% rename from athena-all/src/main/java/run/mone/m78/ip/common/ConfigUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ConfigUtils.java index dfc9454f4..b05751629 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/ConfigUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ConfigUtils.java @@ -14,30 +14,41 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.google.gson.Gson; import com.intellij.ide.util.PropertiesComponent; -import run.mone.m78.ip.bo.TeslaPluginConfig; +import com.xiaomi.youpin.tesla.ip.bo.TeslaPluginConfig; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; import org.apache.commons.lang3.StringUtils; import run.mone.ultraman.AthenaContext; +import java.util.Map; + /** * @author goodjava@qq.com */ public abstract class ConfigUtils { public static TeslaPluginConfig getConfig() { - String v = PropertiesComponent.getInstance().getValue(""); + String v = PropertiesComponent.getInstance().getValue("tesla_plugin_token"); if (StringUtils.isNotEmpty(v)) { TeslaPluginConfig config = new Gson().fromJson(v, TeslaPluginConfig.class); + // 聊天的model设置 String model = config.getModel(); if (StringUtils.isNotEmpty(model)) { AthenaContext.ins().setGptModel(model); AthenaContext.ins().setModelList(config.getModelList()); } + // 非聊天的model设置 + String noChatModel = config.getNoChatModel(); + if (StringUtils.isNotEmpty(noChatModel)) { + AthenaContext.ins().setNoChatModel(noChatModel); + } + + // setup from env if (StringUtils.isEmpty(config.getDashServer())) { config.setDashServer(System.getenv("DASH")); } @@ -48,6 +59,21 @@ public static TeslaPluginConfig getConfig() { config.setChatgptKey(System.getenv("API")); } + // setup from inner config + Map athenaConfig = ResourceUtils.getAthenaConfig(); + if (StringUtils.isEmpty(config.getDashServer())) { + config.setDashServer(athenaConfig.get(Const.CONF_DASH_URL).trim()); + } + if (StringUtils.isEmpty(config.getNickName())) { + config.setNickName(athenaConfig.get(Const.CONF_NICK_NAME).trim()); + } + if (StringUtils.isEmpty(config.getAiProxy())) { + config.setAiProxy(athenaConfig.get(Const.CONF_AI_PROXY_URL).trim()); + } + if (StringUtils.isEmpty(config.getChatServer())) { + config.setChatServer(athenaConfig.get(Const.CONF_PORT).trim()); + } + AthenaContext.ins().setToken(config.getToken()); return config; } diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Const.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Const.java new file mode 100644 index 000000000..7598225f5 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Const.java @@ -0,0 +1,150 @@ +package com.xiaomi.youpin.tesla.ip.common; + +import com.intellij.openapi.util.Key; +import com.intellij.util.messages.Topic; +import run.mone.ultraman.listener.AthenaMessageListener; + +/** + * @author goodjava@qq.com + * @date 2023/6/17 09:37 + */ +public interface Const { + + String MODULE_FILE_NAME = "athena_module.md"; + + String BOT_ID = "botId"; + + String TOKEN = "token"; + + String REQ_PACKAGE = "req_package"; + + String DEFAULT_REQ_PACKAGE = "run.mone.bo"; + + String DISABLE_SEARCH = "disable.search"; + + String AI_PROXY_CHAT = "ai.proxy.chat"; + + String ENABLE_ATHENA_STATUS_BAR = "enable.athena.status.bar"; + + String DISABLE_ACTION_GROUP = "disable.action.group"; + + String BIZ_WRITE = "biz_write"; + + String OPEN_AI_KEY = "open_ai_key"; + + String OPEN_AI_PROXY = "open_ai_proxy"; + + //直接本地调用chatgpt(local模式) + String OPEN_AI_LOCAL = "open_ai_local"; + + //使用bot + String USE_BOT = "use_bot"; + + String INLAY = "inlay"; + + //整体的代码补全功能是否关闭 + String DISABLE_CODE_COMPLETION = "DISABLE_CODE_COMPLETION"; + + //开启Prompt menu + String ENABLE_PROMPT_MENU = "enable.prompt.menu"; + + String STREAM = "stream"; + + String FALSE = "false"; + + String TRUE = "true"; + + //本地测试 + String OPEN_AI_TEST = "open.ai.test"; + + //提问的时候是否开启选中的文本 + String OPEN_SELECT_TEXT = "open.select.text"; + + //本地使用的模型(优先:gpt-4o) + String OPEN_AI_MODEL = "open_ai_model"; + + String SEARCH = "search"; + + int UI_CANCEL_CODE = 555; + + String OPEN_GUIDE = "open.guide"; + + String DEBUG = "debug"; + + //多模态模式 + String VISION = "vision"; + + String CODE_SCRIPT = "code.script"; + + String TREE_SELECT = "tree.select"; + + String BOT_URL = "bot.url"; + + String INLAY_DELAY = "inlay.delay"; + + String INLAY_BOT_ID = "inlay.bot.id"; + + String INLAY_SCOPE = "inlay.scope"; + + String CONF_NICK_NAME = "conf.nickName"; + + String CONF_DASH_URL = "conf.dash.url"; + + String CONF_AI_PROXY_URL = "conf.ai-proxy.url"; + + String CONF_PORT = "conf.port"; + + Key T_KEY = new Key<>("t"); + + Topic ATHENA_TOPIC = new Topic(AthenaMessageListener.class); + + String CONF_M78_URL = "conf.m78.url"; + + String CONF_M78_SPEECH2TEXT = "conf.a2t.endpoint"; + + String CONF_M78_TEXT2SPEECH = "conf.t2a.endpoint"; + + String CONF_M78_UPLOAD_CODE_INFO = "conf.upload.info.endpoint"; + + String CONF_M78_CODE_GEN_WITH_ENTER = "conf.codegen.trigger.enter"; + + String PROMPT_LABEL_TYPE = "type"; + + String CONF_COMPLETION_TYPE = "conf.completion.type"; + + //生成代码的prompt name + String GENERATE_CODE = "biz_sidecar"; + + //生产代码的注释 + String GENERATE_CODE_COMMENT = "biz_sidecar_comment"; + + //单元测试的prompt name + String UNIT_TEST = "test_code"; + + String CLIENT_VERSION = "clientVersion"; + + String CLIENT_NAME = "clientName"; + + String PLUGIN_NAME = "Mione"; + + String MIONE_CONSOLE_NAME = "MioneConsole"; + + // 右侧聊天用的prompt name + String ATHENA_CHAT = "athena_chat"; + + // 代码检查的prompt name + String CODE_REVIEW = "bot_stream"; + + // 配置用于控制右侧聊天是否走BOT逻辑,默认走 + String CONF_CHAT_USE_BOT = "conf.chat.use.bot"; + + // 执行BOT传递参数的模型的key + String AI_MODEL_PARAM_KEY = "model"; + + // 使用BOT默认模型的选项 + String USE_BOT_MODEL = "默认"; + + // 生成单测prompt name + String GENERATE_UNIT_TEST = "generate_unit_test"; + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Context.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Context.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/common/Context.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Context.java index c783f4641..ea9f9f011 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/Context.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Context.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.intellij.openapi.project.Project; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/DownloadUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/DownloadUtils.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/common/DownloadUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/DownloadUtils.java index 53d5c7d89..f72f5d585 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/DownloadUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/DownloadUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import java.io.IOException; diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/TaskService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ErrorMessage.java similarity index 74% rename from athena-all/src/main/java/run/mone/m78/ip/service/TaskService.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ErrorMessage.java index a105ab331..a90d53f3d 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/TaskService.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ErrorMessage.java @@ -14,19 +14,14 @@ * limitations under the License. */ -package run.mone.m78.ip.service; - -import java.util.List; +package com.xiaomi.youpin.tesla.ip.common; /** - * @Author goodjava@qq.com - * @Date 2021/11/9 14:04 + * @author shanwb + * @date 2024-07-05 */ -public class TaskService { - +public class ErrorMessage { - public List tasks(String name) { - return null; - } + public static final String ERR_NOT_IN_CLASS_SCOPE = "请检查当前位置是否在class范围内{}"; } diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Events.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Events.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/common/Events.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Events.java index 58e8ce0ca..42f4c876b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/Events.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Events.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.intellij.openapi.application.ApplicationManager; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/FileUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/FileUtils.java similarity index 98% rename from athena-all/src/main/java/run/mone/m78/ip/common/FileUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/FileUtils.java index 192d444fb..74556ed4d 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/FileUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/FileUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import org.apache.commons.io.IOUtils; import org.beetl.core.Configuration; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/GlobalConfig.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/GlobalConfig.java similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/common/GlobalConfig.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/GlobalConfig.java index 2117c579b..b26f8c6be 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/GlobalConfig.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/GlobalConfig.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; public class GlobalConfig { public static final String PLUGIN_NAME = "youpin_plugin"; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/IdeaPluginVersion.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/IdeaPluginVersion.java similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/common/IdeaPluginVersion.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/IdeaPluginVersion.java index 5e68a42c8..9461f5d91 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/IdeaPluginVersion.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/IdeaPluginVersion.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/JavaClassUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/JavaClassUtils.java new file mode 100644 index 000000000..dca29ad1f --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/JavaClassUtils.java @@ -0,0 +1,120 @@ +package com.xiaomi.youpin.tesla.ip.common; + +import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiShortNamesCache; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + * @date 2023/4/12 11:05 + */ +public abstract class JavaClassUtils { + + /** + * Create a class. + */ + public static void createClass(AnActionEvent e) { + createClass(e.getProject(), e.getData(PlatformDataKeys.EDITOR), "abc", ""); + } + + public static void createClass(Project project, Editor editor, String name, String code) { + if (project == null) { + return; + } + String classContent = code; + @NotNull PsiFile javaClassFile = PsiFileFactory.getInstance(project).createFileFromText(name, JavaFileType.INSTANCE, classContent); + javaClassFile.setName(name + ".java"); + //Add Java classes to the project. + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiDirectory containerDirectory = psiFile.getContainingDirectory(); + WriteCommandAction.runWriteCommandAction(project, () -> { + containerDirectory.add(javaClassFile); + }); + } + + + + public static void createClass(Project project, Editor editor, String name, String code, boolean testClass) { + if (project == null) { + return; + } + String classContent = code; + @NotNull PsiFile javaClassFile = PsiFileFactory.getInstance(project).createFileFromText(name, JavaFileType.INSTANCE, classContent); + javaClassFile.setName(name + ".java"); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiDirectory containerDirectory = testClass ? CodeService.getSourceDirectory(project, "", true) : psiFile.getContainingDirectory(); + WriteCommandAction.runWriteCommandAction(project, () -> { + containerDirectory.add(javaClassFile); + }); + } + + public static void createClass(Project project, Editor editor, String name, String code, boolean testClass, String packagePath) { + if (project == null) { + return; + } + String classContent = code; + @NotNull PsiFile javaClassFile = PsiFileFactory.getInstance(project).createFileFromText(name, JavaFileType.INSTANCE, classContent); + javaClassFile.setName(name + ".java"); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiDirectory containerDirectory = testClass ? CodeService.getSourceDirectory(project, true, packagePath) : psiFile.getContainingDirectory(); + WriteCommandAction.runWriteCommandAction(project, () -> { + containerDirectory.add(javaClassFile); + // 生成后打开文件 + openClass(project, name); + }); + } + + + public static void openClass(AnActionEvent e) { + // 获取当前项目实例 + Project project = e.getProject(); + if (project == null) { + return; + } + // 定位目标Java类 + String targetClassName = "MyNewJavaClass"; + PsiClass[] targetClasses = PsiShortNamesCache.getInstance(project).getClassesByName(targetClassName, GlobalSearchScope.allScope(project)); + if (targetClasses.length > 0) { + PsiClass targetClass = targetClasses[0]; + PsiFile containingFile = targetClass.getContainingFile(); + // 打开目标Java文件 + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + fileEditorManager.openFile(containingFile.getVirtualFile(), true); + } + } + + public static void openClass(Project project, String className) { + // 获取当前项目实例 + if (project == null) { + return; + } + // 定位目标Java类 + String targetClassName = className; + PsiClass[] targetClasses = PsiShortNamesCache.getInstance(project).getClassesByName(targetClassName, GlobalSearchScope.allScope(project)); + if (targetClasses.length > 0) { + PsiClass targetClass = targetClasses[0]; + PsiFile containingFile = targetClass.getContainingFile(); + // 打开目标Java文件 + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + fileEditorManager.openFile(containingFile.getVirtualFile(), true); + } + } + + + public static String getClassName(String className) { + String[] classNameParts = className.split("\\."); + String simpleClassName = classNameParts[classNameParts.length - 1]; + return simpleClassName; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/MessageQueue.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/MessageQueue.java similarity index 93% rename from athena-all/src/main/java/run/mone/m78/ip/common/MessageQueue.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/MessageQueue.java index 7eb5a0717..636f294e4 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/MessageQueue.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/MessageQueue.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; -import run.mone.m78.ip.bo.Response; +import com.xiaomi.youpin.tesla.ip.bo.Response; import java.util.HashMap; import java.util.Map; +import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; /** diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Mp3Player.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Mp3Player.java similarity index 85% rename from athena-all/src/main/java/run/mone/m78/ip/common/Mp3Player.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Mp3Player.java index b0b1ead8c..faca14455 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/Mp3Player.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Mp3Player.java @@ -14,14 +14,20 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.intellij.openapi.diagnostic.Logger; +import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; +import javax.sound.sampled.DataLine; import javax.sound.sampled.UnsupportedAudioFileException; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.net.URL; import java.util.Objects; /** @@ -36,6 +42,11 @@ public class Mp3Player { private static final Logger log = Logger.getInstance(Mp3Player.class); + public static void main(String[] args) throws IOException, UnsupportedAudioFileException { +// Mp3Player player = new Mp3Player(); + + } + public void playMp3Url(String url) throws UnsupportedAudioFileException, IOException { } diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Mp3PlayerV2.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Mp3PlayerV2.java similarity index 97% rename from athena-all/src/main/java/run/mone/m78/ip/common/Mp3PlayerV2.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Mp3PlayerV2.java index 51214ab51..8e1c1d49b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/Mp3PlayerV2.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Mp3PlayerV2.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.intellij.openapi.diagnostic.Logger; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/NotificationCenter.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/NotificationCenter.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/common/NotificationCenter.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/NotificationCenter.java index 92d2c896f..071c54e52 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/NotificationCenter.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/NotificationCenter.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; /** * @Author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/OggPlayer.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/OggPlayer.java similarity index 98% rename from athena-all/src/main/java/run/mone/m78/ip/common/OggPlayer.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/OggPlayer.java index a0287318f..9b88522d2 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/OggPlayer.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/OggPlayer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import javax.sound.sampled.AudioFormat; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/OpenImageConsumer.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/OpenImageConsumer.java similarity index 97% rename from athena-all/src/main/java/run/mone/m78/ip/common/OpenImageConsumer.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/OpenImageConsumer.java index 6e101a960..01a7fa7c9 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/OpenImageConsumer.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/OpenImageConsumer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.intellij.openapi.actionSystem.DataContext; @@ -41,7 +41,7 @@ public class OpenImageConsumer implements Consumer { private static final Logger LOG = Logger.getInstance(OpenImageConsumer.class); - private String imgUrl = ""; + private String imgUrl = "xxx"; public OpenImageConsumer() { } diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/OpenTextConsumer.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/OpenTextConsumer.java similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/common/OpenTextConsumer.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/OpenTextConsumer.java index b824d886e..0bee7af36 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/OpenTextConsumer.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/OpenTextConsumer.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; @@ -27,6 +28,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; +import java.util.UUID; import java.util.function.Consumer; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/PluginVersion.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/PluginVersion.java similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/common/PluginVersion.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/PluginVersion.java index accaa8efd..4f35b3d5c 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/PluginVersion.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/PluginVersion.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; /** * @Author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ProjectCache.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ProjectCache.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/common/ProjectCache.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ProjectCache.java index b4dc5d0d5..0bc6c81e4 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/ProjectCache.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ProjectCache.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Prompt.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Prompt.java new file mode 100644 index 000000000..49d8f40e7 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Prompt.java @@ -0,0 +1,267 @@ +package com.xiaomi.youpin.tesla.ip.common; + +import com.google.common.base.Splitter; +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.ApplicationInfo; +import com.xiaomi.youpin.tesla.ip.bo.*; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.compress.utils.Lists; +import org.apache.commons.lang3.StringUtils; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.bo.Version; +import run.mone.ultraman.common.SafeRun; +import run.mone.ultraman.http.HttpClient; + +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @author caobaoyu + * @date 2023/4/15 08:38 + */ +@Slf4j +public class Prompt { + + private static Map promptMap = new HashMap<>(); + + private static CopyOnWriteArrayList promptMeta = new CopyOnWriteArrayList<>(); + + private static String zAddr = ""; + + private static AtomicBoolean loadFinish = new AtomicBoolean(); + + public static String get(String key) { + return promptMap.get(key); + } + + public static List getPromptMeta() { + return promptMeta; + } + + public static boolean isLoadFinish() { + return loadFinish.get(); + } + + + private static Gson gson = new Gson(); + + public static void flush() { + init(); + } + + public static int size() { + return promptMap.size(); + } + + + public static void init() { + zAddr = reportPluginInfo(); + if (StringUtils.isEmpty(zAddr)) { + return; + } + promptMeta.clear(); + promptMeta.addAll(getPrompt()); + ConfigCenter.init(zAddr); + loadFinish.set(true); + } + + public static List getPrompt() { + try { + ZRequestPram param = new ZRequestPram(); + String zToken = ConfigUtils.getConfig().getzToken(); + String url = zAddr + "/list"; + param.setType(64); + param.setToken(zToken); + String res = HttpClient.callHttpServer(url, "get_prompt_list", gson.toJson(param)); + List data = gson.fromJson(res, new TypeToken>() { + }.getType()); + return convertZResToInfo(data); + } catch (Throwable ex) { + log.error(ex.getMessage()); + NotificationCenter.notice("get prompt error:" + ex.getMessage(), NotificationType.ERROR, true); + return Lists.newArrayList(); + } + } + + + public static PromptInfo getPrompt(int type, String name) { + try { + ZRequestPram param = new ZRequestPram(); + String zToken = ConfigUtils.getConfig().getzToken(); + String url = zAddr + "/list"; + param.setType(type); + param.setName(name); + param.setToken(zToken); + String res = HttpClient.callHttpServer(url, "get_prompt:" + name, gson.toJson(param)); + List data = gson.fromJson(res, new TypeToken>() { + }.getType()); + List list = convertZResToInfo(data); + if (list.size() > 0) { + return list.get(0); + } + } catch (Throwable ex) { + log.error(ex.getMessage()); + NotificationCenter.notice("get prompt error:" + ex.getMessage(), NotificationType.ERROR, true); + } + return null; + } + + + /** + * 将Z的结果转换为实体 + * + * @param data + * @return + */ + private static List convertZResToInfo(List data) { + return data.stream().map(v -> PromptInfo.builder() + .id(v.getId()) + .promptName(v.getName()) + .tags(v.getTags()) + .data(v.getData()) + .labels(getLabels(v)) + .collected(v.getCollected()) + .usedTimes(v.getUsedTimes()) + .meta(v.getMeta()) + .desc(v.getDescription()) + .addon(v.getAddon()) + .addon_metas(v.getAddon_metas()) + .collectedSort(v.getCollectedSort()) + .build()).toList(); + } + + //用user的覆盖即可 + private static Map getLabels(ZPromptRes v) { + if (MapUtils.isNotEmpty(v.getUserLabels())) { + v.getLabels().putAll(v.getUserLabels()); + } + return v.getLabels(); + } + + public static List promptList(String tagName) { + return promptMeta.stream().filter(it -> { + List tags = it.getTags(); + if (null == tags) { + return false; + } + return tags.stream().filter(tag -> tag.getName().equals(tagName)).findAny().isPresent(); + }).collect(Collectors.toList()); + } + + public static boolean containsTag(List tags, String tagName) { + return tags.stream().filter(tag -> tag.getName().equals(tagName)).findAny().isPresent(); + } + + /** + * 查询是那种类型 + * + * @param info + * @return + */ + public static PromptType getPromptType(PromptInfo info) { + List tags = info.getTags(); + if (null == tags) { + return PromptType.modifyMethod; + } + + for (PromptType type : PromptType.values()) { + if (containsTag(info.getTags(), type.name())) { + return type; + } + } + return PromptType.modifyMethod; + } + + + public static String reportPluginInfo() { + try { + ZAddrRes zAddrRes = zAddrRes(); + initConfig(zAddrRes); + return zAddrRes.getAddr(); + } catch (Throwable ex) { + log.error(ex.getMessage()); + return ""; + } + } + + public static ZAddrRes zAddrRes() { + String aiProxy = ResourceUtils.getAthenaConfig().get(Const.CONF_AI_PROXY_URL); + AthenaReq req = AthenaReq.builder() + .userName(ConfigUtils.getConfig().getNickName()) + .zzToken(ConfigUtils.getConfig().getzToken()) + .version(new Version().toString()) + .os(System.getProperty("os.name").toLowerCase()) + .ideaVersion(ApplicationInfo.getInstance().getBuild().asString()) + .time(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())) + .build(); + String res = HttpClient.callHttpServer(aiProxy + "/report", "report", gson.toJson(req)); + ZAddrRes zAddrRes = gson.fromJson(res, ZAddrRes.class); + AthenaContext.ins().setZAddr(zAddrRes.getAddr()); + AthenaContext.ins().setModels(zAddrRes.getModelsV2()); + AthenaContext.ins().setUserName(zAddrRes.getUserName()); + AthenaContext.ins().convertModelsToModelMap(); + return zAddrRes; + } + + private static void initConfig(ZAddrRes zAddrRes) { + SafeRun.run(() -> { + if (StringUtils.isNotEmpty(zAddrRes.getAthenaConfig())) { + String config = zAddrRes.getAthenaConfig(); + Splitter.on(",").split(config).forEach(it -> { + List list = Splitter.on(":").splitToList(it); + if (null != list && list.size() == 2) { + ResourceUtils.putConfigIfAbsent(list.get(0), list.get(1)); + } + }); + } + }); + } + + + public static PromptInfo getPromptInfo(String promptName) { + return promptMeta.stream().filter(it -> it.getPromptName().equals(promptName)).findAny().get(); + } + + public static List getPromptInfoByTag(String tag) { + return promptMeta.stream().filter(promptInfo -> containsTag(promptInfo.getTags(), tag)).collect(Collectors.toList()); + } + + public static List getCollected() { + return promptMeta.stream().filter(PromptInfo::isCollected).sorted(Comparator.comparing(PromptInfo::getCollectedSort)).collect(Collectors.toList()); + } + + /** + * 获取使用次数最多的size个prompt + * + * @param size + * @return + */ + public static List getMostUsed(int size) { + return promptMeta.stream().sorted(Comparator.comparing(PromptInfo::getUsedTimes).reversed()).limit(size).collect(Collectors.toList()); + } + + /** + * 获取某个标签下使用次数最多的size个prompt + * + * @param size + * @param tag + * @return + */ + public static List getMostUsed(int size, String tag) { + return promptMeta.stream().filter(promptInfo -> containsTag(promptInfo.getTags(), tag)) + .sorted(Comparator.comparing(PromptInfo::getUsedTimes).reversed()).limit(size).collect(Collectors.toList()); + } + + public static String getzAddr() { + return zAddr; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/PromptType.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/PromptType.java similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/common/PromptType.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/PromptType.java index 8c7a9c8a2..447e60a04 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/PromptType.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/PromptType.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; /** * @author goodjava@qq.com @@ -30,6 +30,7 @@ public enum PromptType { generateMiapiMethod("根据miapi知识库生成某接口调用方法"), generateTestMethod("生成测试代码"), generateInterface("提取公共方法生成接口"), + executeBot("执行bot(m78)"), question("ai会向你提问") ; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ProxyUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ProxyUtils.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/common/ProxyUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ProxyUtils.java index 89df49934..19dc27bdc 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/ProxyUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/ProxyUtils.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import org.apache.commons.lang3.StringUtils; diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Safe.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Safe.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/common/Safe.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Safe.java index d2e123e91..6a1981182 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/Safe.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/Safe.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import lombok.extern.slf4j.Slf4j; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/StringUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/StringUtils.java new file mode 100644 index 000000000..13bcd9fc1 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/StringUtils.java @@ -0,0 +1,51 @@ +package com.xiaomi.youpin.tesla.ip.common; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author goodjava@qq.com + * @date 2023/5/18 22:26 + */ +public abstract class StringUtils { + + public static Pattern endingKeywordPattern = Pattern.compile("(\\(|(|\\\\)(class|method|project|module)(\\)|)|\\\\)?$"); + + + public static String convertToCamelCase(String input) { + StringBuilder result = new StringBuilder(); + String[] words = input.split("_"); + result.append(words[0]); + for (int i = 1; i < words.length; i++) { + String word = words[i]; + String capitalizedWord = Character.toUpperCase(word.charAt(0)) + word.substring(1); + result.append(capitalizedWord); + } + return result.toString(); + } + + + //写一个正则,从结尾提取出我期望的字符(class、method、project、module),接下来描述时我用x代表目标字符,结尾场景有这三种情况:(x)、(x)、\x,不满足提取诉求的返回空 + public static String extractEndingKeyword(String input) { + if (org.apache.commons.lang3.StringUtils.isEmpty(input)) { + return ""; + } + input = extractMultilineComment(input); + Matcher matcher = endingKeywordPattern.matcher(input); + if (matcher.find()) { + return matcher.group(2); + } + return ""; + } + + //写一个方法,输入一个字符串,判断是否是多行注释,如果是多行注释,请把注释符号全去掉,只返回注释文本 + public static String extractMultilineComment(String input) { + if (input == null || !input.startsWith("/*") || !input.endsWith("*/")) { + return input; + } + return input.substring(2, input.length() - 2).replaceAll("\\*", "").trim(); + } + + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/TeslaConfigurable.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/TeslaConfigurable.java similarity index 71% rename from athena-all/src/main/java/run/mone/m78/ip/common/TeslaConfigurable.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/TeslaConfigurable.java index 74d2a66a3..635887dba 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/TeslaConfigurable.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/TeslaConfigurable.java @@ -14,19 +14,20 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.google.gson.Gson; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.options.SearchableConfigurable; -import run.mone.m78.ip.bo.TeslaPluginConfig; -import run.mone.m78.ip.ui.ConfigUi; +import com.xiaomi.youpin.tesla.ip.bo.TeslaPluginConfig; +import com.xiaomi.youpin.tesla.ip.ui.ConfigUi; import org.apache.commons.lang3.mutable.MutableBoolean; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.listener.bo.CompletionEnum; import javax.swing.*; import java.util.ArrayList; @@ -74,7 +75,6 @@ public boolean isModified() { public void apply() { TeslaPluginConfig config = new TeslaPluginConfig(); String oldServer = config.getDashServer(); - config.setDashServer(configUi.getDashServerTextField().getText()); if (null != config.getDashServer() && (null == oldServer || !config.getDashServer().equals(oldServer))) { Safe.run(() -> { if (null != AthenaContext.ins().getAthenaTreeKeyAdapter()) { @@ -82,20 +82,26 @@ public void apply() { } }); } - config.setNickName(configUi.getNickNameTextField().getText()); config.setzToken(configUi.getzTokenPassword().getText().trim()); - config.setAiProxy(configUi.getAiProxyTextField().getText().trim()); - if (configUi.getModelComboBox().getModel().getSize() > 0 && null != configUi.getModelComboBox().getSelectedItem()) { - config.setModel(configUi.getModelComboBox().getSelectedItem().toString()); + // 聊天模型的设置 + if (configUi.getChatModelComboBox().getModel().getSize() > 0 && null != configUi.getChatModelComboBox().getSelectedItem()) { + config.setModel(configUi.getChatModelComboBox().getSelectedItem().toString()); AthenaContext.ins().setGptModel(config.getModel()); } - ComboBoxModel model = configUi.getModelComboBox().getModel(); + // 非聊天模型的设置 + if (configUi.getNoChatModelComboBox().getModel().getSize() > 0 && null != configUi.getNoChatModelComboBox().getSelectedItem()) { + config.setNoChatModel(configUi.getNoChatModelComboBox().getSelectedItem().toString()); + AthenaContext.ins().setNoChatModel(config.getNoChatModel()); + } + ComboBoxModel model = configUi.getChatModelComboBox().getModel(); List list = new ArrayList<>(); for (int i = 0; i < model.getSize(); i++) { list.add(model.getElementAt(i).toString()); } config.setModelList(list); - PropertiesComponent.getInstance().setValue("", new Gson().toJson(config)); + ComboBoxModel completionMode = configUi.getCompletionMode().getModel(); + config.setCompletionMode(CompletionEnum.getTypeEnumByDesc(completionMode.getSelectedItem().toString())); + PropertiesComponent.getInstance().setValue("tesla_plugin_token", new Gson().toJson(config)); configUi.getModified().setValue(false); new Thread(Prompt::flush).start(); diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/UltramanEvent.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/UltramanEvent.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/common/UltramanEvent.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/UltramanEvent.java index 563b88143..10ebb2223 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/UltramanEvent.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/UltramanEvent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; /** * @Author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/UltramanNotifier.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/UltramanNotifier.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/common/UltramanNotifier.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/UltramanNotifier.java index fa09a69a2..6437c5703 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/common/UltramanNotifier.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/UltramanNotifier.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.common; +package com.xiaomi.youpin.tesla.ip.common; import com.intellij.util.messages.Topic; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/VersionUtil.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/VersionUtil.java new file mode 100644 index 000000000..0c7c9ca46 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/common/VersionUtil.java @@ -0,0 +1,80 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 com.xiaomi.youpin.tesla.ip.common; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * @author shanwb + * @date 2024-06-18 + */ +public class VersionUtil { + + private static final String PLUGIN_VERSION_KEY = "pluginVersion"; + + public static volatile String ATHENA_VERSION = null; + + public static volatile String MINI_ATHENA_VERSION = "2025.06.13.1"; + + //读取src/main/resources/athena.properties文件中的pluginVersion属性,注意在jar环境下也能正确读取到(method) + public static String getAthenaPluginVersion() { + if (null == ATHENA_VERSION) { + synchronized (VersionUtil.class) { + if (null == ATHENA_VERSION) { // Double-checked locking + Properties properties = new Properties(); + try (final InputStream inputStream = VersionUtil.class.getResourceAsStream("/athena.properties");) { + if (inputStream != null) { + properties.load(inputStream); + ATHENA_VERSION = properties.getProperty("pluginVersion"); + } else { + throw new IOException("Athena properties file not found"); + } + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + } + } + + return ATHENA_VERSION; + } + + //判断两个版本字符串 谁的版本更新, 版本字符串都是类似这样子的格式:2024.06.18.1 (method) + public static int compareVersions(String version1, String version2) { + String[] parts1 = version1.split("\\."); + String[] parts2 = version2.split("\\."); + + int length = Math.max(parts1.length, parts2.length); + for (int i = 0; i < length; i++) { + int v1 = i < parts1.length ? Integer.parseInt(parts1[i]) : 0; + int v2 = i < parts2.length ? Integer.parseInt(parts2[i]) : 0; + if (v1 != v2) { + return v1 - v2; + } + } + return 0; + } + + public static boolean isVersionNeedUpgrades() { + return compareVersions(getAthenaPluginVersion(), MINI_ATHENA_VERSION) >= 0; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/ChatComponent.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/ChatComponent.java similarity index 90% rename from athena-all/src/main/java/run/mone/m78/ip/component/ChatComponent.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/ChatComponent.java index 5d3b09dd9..64771e3b3 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/component/ChatComponent.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/ChatComponent.java @@ -14,12 +14,13 @@ * limitations under the License. */ -package run.mone.m78.ip.component; +package com.xiaomi.youpin.tesla.ip.component; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.ui.ChatUi; +import com.xiaomi.youpin.tesla.ip.ui.BuildUi; +import com.xiaomi.youpin.tesla.ip.ui.ChatUi; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/CreateProjectComponent.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/CreateProjectComponent.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/component/CreateProjectComponent.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/CreateProjectComponent.java index 75385dd22..e8179ac27 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/component/CreateProjectComponent.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/CreateProjectComponent.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package run.mone.m78.ip.component; +package com.xiaomi.youpin.tesla.ip.component; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.ui.CodeGeneratorUi; +import com.xiaomi.youpin.tesla.ip.ui.CodeGeneratorUi; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/CreateSpringBootProjectComponent.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/CreateSpringBootProjectComponent.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/component/CreateSpringBootProjectComponent.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/CreateSpringBootProjectComponent.java index 11fecba86..cb48e6464 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/component/CreateSpringBootProjectComponent.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/CreateSpringBootProjectComponent.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package run.mone.m78.ip.component; +package com.xiaomi.youpin.tesla.ip.component; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.ui.SpringBootProGenerator; +import com.xiaomi.youpin.tesla.ip.ui.CodeGeneratorUi; +import com.xiaomi.youpin.tesla.ip.ui.SpringBootProGenerator; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/FilterComponent.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/FilterComponent.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/component/FilterComponent.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/FilterComponent.java index 2cf797090..39fc83d61 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/component/FilterComponent.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/FilterComponent.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package run.mone.m78.ip.component; +package com.xiaomi.youpin.tesla.ip.component; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.ui.FilterUi; +import com.xiaomi.youpin.tesla.ip.ui.FilterUi; public class FilterComponent implements ApplicationComponent { diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/NaviComponent.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/NaviComponent.java similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/component/NaviComponent.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/NaviComponent.java index bcc8eaae9..3366efc7b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/component/NaviComponent.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/NaviComponent.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package run.mone.m78.ip.component; +package com.xiaomi.youpin.tesla.ip.component; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.ui.NaviUi; +import com.xiaomi.youpin.tesla.ip.ui.ChatUi; +import com.xiaomi.youpin.tesla.ip.ui.NaviUi; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/PluginComponent.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/PluginComponent.java similarity index 93% rename from athena-all/src/main/java/run/mone/m78/ip/component/PluginComponent.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/PluginComponent.java index c2d307e63..6b2006452 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/component/PluginComponent.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/PluginComponent.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package run.mone.m78.ip.component; +package com.xiaomi.youpin.tesla.ip.component; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.ui.BuildUi; +import com.xiaomi.youpin.tesla.ip.ui.BuildUi; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/TeslaAppComponent.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/TeslaAppComponent.java similarity index 97% rename from athena-all/src/main/java/run/mone/m78/ip/component/TeslaAppComponent.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/TeslaAppComponent.java index 8d0233f94..cb8b11a43 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/component/TeslaAppComponent.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/TeslaAppComponent.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.component; +package com.xiaomi.youpin.tesla.ip.component; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -40,13 +40,13 @@ import com.intellij.util.Consumer; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.MessageBusConnection; +import com.xiaomi.youpin.tesla.ip.bo.*; +import com.xiaomi.youpin.tesla.ip.common.*; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.UltramanService; +import com.xiaomi.youpin.tesla.ip.util.ProjectUtils; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; -import run.mone.m78.ip.bo.*; -import run.mone.m78.ip.common.*; -import run.mone.m78.ip.service.CodeService; -import run.mone.m78.ip.service.UltramanService; -import run.mone.m78.ip.util.ProjectUtils; import run.mone.ultraman.bo.ParamsInfo; import run.mone.ultraman.event.AthenaEventBus; import run.mone.ultraman.listener.AthenaFileDocumentManagerListener; @@ -54,6 +54,7 @@ import run.mone.ultraman.listener.AthenaMessageListenerImpl; import run.mone.ultraman.service.AutoFlushBizService; +import java.net.URI; import java.util.*; import java.util.stream.Collectors; diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/VersionComponent.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/VersionComponent.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/component/VersionComponent.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/VersionComponent.java index 65a4b34e3..bba4fa8db 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/component/VersionComponent.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/VersionComponent.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package run.mone.m78.ip.component; +package com.xiaomi.youpin.tesla.ip.component; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.ui.VersionUi; +import com.xiaomi.youpin.tesla.ip.ui.VersionUi; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaProjectComment.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/project/AthenaProjectComment.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaProjectComment.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/project/AthenaProjectComment.java index a3791e924..6fcc464c9 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaProjectComment.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/project/AthenaProjectComment.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.component.project; +package com.xiaomi.youpin.tesla.ip.component.project; import com.intellij.ide.projectView.ProjectView; @@ -6,7 +6,7 @@ import com.intellij.ide.projectView.impl.ProjectViewTree; import com.intellij.openapi.components.ProjectComponent; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.common.NotificationCenter; +import com.xiaomi.youpin.tesla.ip.common.NotificationCenter; import org.jetbrains.annotations.NotNull; import javax.swing.tree.TreePath; diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaTreeSelectionListener.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/project/AthenaTreeSelectionListener.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaTreeSelectionListener.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/project/AthenaTreeSelectionListener.java index e91669c28..1b7c69f2a 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/component/project/AthenaTreeSelectionListener.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/component/project/AthenaTreeSelectionListener.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.component.project; +package com.xiaomi.youpin.tesla.ip.component.project; import com.intellij.ide.projectView.impl.nodes.ClassTreeNode; import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode; @@ -6,7 +6,7 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiPackage; -import run.mone.m78.ip.bo.ClassInfo; +import com.xiaomi.youpin.tesla.ip.bo.ClassInfo; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Nullable; import run.mone.ultraman.bo.PackageInfo; diff --git a/athena-all/src/main/java/run/mone/m78/ip/consumer/CodeConsumer.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/consumer/CodeConsumer.java similarity index 58% rename from athena-all/src/main/java/run/mone/m78/ip/consumer/CodeConsumer.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/consumer/CodeConsumer.java index f0a9cb23a..c69090dda 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/consumer/CodeConsumer.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/consumer/CodeConsumer.java @@ -1,10 +1,11 @@ -package run.mone.m78.ip.consumer; +package com.xiaomi.youpin.tesla.ip.consumer; import com.intellij.openapi.editor.Editor; -import run.mone.m78.ip.bo.AiMessage; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.MessageConsumer; -import run.mone.m78.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.bo.AiMessage; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.MessageConsumer; +import com.xiaomi.youpin.tesla.ip.common.NotificationCenter; +import com.xiaomi.youpin.tesla.ip.service.CodeService; /** * @author goodjava@qq.com @@ -28,6 +29,7 @@ public void onEvent(AiMessage message) { @Override public void end(AiMessage message) { +// NotificationCenter.notice(com.xiaomi.youpin.tesla.ip.bo.Message.finishMsg); } } diff --git a/athena-all/src/main/java/run/mone/m78/ip/consumer/FinishConsumer.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/consumer/FinishConsumer.java similarity index 77% rename from athena-all/src/main/java/run/mone/m78/ip/consumer/FinishConsumer.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/consumer/FinishConsumer.java index cabfdf786..35fcc1df4 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/consumer/FinishConsumer.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/consumer/FinishConsumer.java @@ -1,7 +1,7 @@ -package run.mone.m78.ip.consumer; +package com.xiaomi.youpin.tesla.ip.consumer; -import run.mone.m78.ip.bo.AiMessage; -import run.mone.m78.ip.bo.MessageConsumer; +import com.xiaomi.youpin.tesla.ip.bo.AiMessage; +import com.xiaomi.youpin.tesla.ip.bo.MessageConsumer; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/AthenaTableCellEditor.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/AthenaTableCellEditor.java similarity index 93% rename from athena-all/src/main/java/run/mone/m78/ip/dialog/AthenaTableCellEditor.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/AthenaTableCellEditor.java index 37012557f..9886f7e10 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/dialog/AthenaTableCellEditor.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/AthenaTableCellEditor.java @@ -1,18 +1,18 @@ -package run.mone.m78.ip.dialog; +package com.xiaomi.youpin.tesla.ip.dialog; import com.google.common.base.Joiner; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; -import run.mone.m78.ip.bo.ClassInfo; -import run.mone.m78.ip.bo.CreateClassRes; -import run.mone.m78.ip.bo.Message; -import run.mone.m78.ip.bo.prompt.PromptParamType; -import run.mone.m78.ip.ui.CreateClassUi; -import run.mone.m78.ip.util.ProjectUtils; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.bo.prompt.PromptParam; -import run.mone.m78.ip.common.Const; -import run.mone.m78.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.bo.ClassInfo; +import com.xiaomi.youpin.tesla.ip.bo.CreateClassRes; +import com.xiaomi.youpin.tesla.ip.bo.Message; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.prompt.PromptParam; +import com.xiaomi.youpin.tesla.ip.bo.prompt.PromptParamType; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.ui.CreateClassUi; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.util.ProjectUtils; import lombok.Setter; import org.apache.commons.lang3.StringUtils; import run.mone.ultraman.bo.PackageInfo; diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/ChromeDialog.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/ChromeDialog.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/dialog/ChromeDialog.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/ChromeDialog.java index b92f973f6..5b0e2c7e7 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/dialog/ChromeDialog.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/ChromeDialog.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.dialog; +package com.xiaomi.youpin.tesla.ip.dialog; import com.intellij.openapi.application.ApplicationInfo; import com.intellij.openapi.application.ApplicationManager; @@ -7,8 +7,8 @@ import com.intellij.ui.jcef.JBCefApp; import com.intellij.ui.jcef.JBCefBrowser; import com.intellij.ui.jcef.JBCefClient; -import run.mone.m78.ip.listener.ChromeMessageRouterHandler; -import run.mone.m78.ip.util.ScreenSizeUtils; +import com.xiaomi.youpin.tesla.ip.listener.ChromeMessageRouterHandler; +import com.xiaomi.youpin.tesla.ip.util.ScreenSizeUtils; import org.cef.browser.CefBrowser; import org.cef.browser.CefFrame; import org.cef.browser.CefMessageRouter; diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogContext.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DialogContext.java similarity index 81% rename from athena-all/src/main/java/run/mone/m78/ip/dialog/DialogContext.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DialogContext.java index d968f744f..17a8f8933 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogContext.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DialogContext.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.dialog; +package com.xiaomi.youpin.tesla.ip.dialog; import com.intellij.openapi.module.Module; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogReq.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DialogReq.java similarity index 90% rename from athena-all/src/main/java/run/mone/m78/ip/dialog/DialogReq.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DialogReq.java index 037dbea20..d1ee6726b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogReq.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DialogReq.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.dialog; +package com.xiaomi.youpin.tesla.ip.dialog; import com.intellij.openapi.module.Module; import lombok.Builder; diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogResult.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DialogResult.java similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/dialog/DialogResult.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DialogResult.java index 3c03070ff..149d0e162 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/dialog/DialogResult.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DialogResult.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.dialog; +package com.xiaomi.youpin.tesla.ip.dialog; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/DirectoryTreeDialog.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DirectoryTreeDialog.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/dialog/DirectoryTreeDialog.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DirectoryTreeDialog.java index 7df5af0f8..a8fa09849 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/dialog/DirectoryTreeDialog.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/DirectoryTreeDialog.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.dialog; +package com.xiaomi.youpin.tesla.ip.dialog; import com.intellij.icons.AllIcons; import com.intellij.ide.util.treeView.NodeRenderer; @@ -8,8 +8,8 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.treeStructure.Tree; -import run.mone.m78.ip.util.ProjectUtils; -import run.mone.m78.ip.util.ScreenSizeUtils; +import com.xiaomi.youpin.tesla.ip.util.ProjectUtils; +import com.xiaomi.youpin.tesla.ip.util.ScreenSizeUtils; import lombok.Getter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/MarkdownDialog.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/MarkdownDialog.java new file mode 100644 index 000000000..de437857b --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/MarkdownDialog.java @@ -0,0 +1,203 @@ +//package com.xiaomi.youpin.tesla.ip.dialog; +// +//import com.google.common.collect.Lists; +//import com.intellij.openapi.application.ApplicationManager; +//import com.intellij.openapi.editor.Document; +//import com.intellij.openapi.editor.Editor; +//import com.intellij.openapi.editor.EditorFactory; +//import com.intellij.openapi.editor.event.DocumentEvent; +//import com.intellij.openapi.editor.event.DocumentListener; +//import com.intellij.openapi.fileTypes.FileType; +//import com.intellij.openapi.fileTypes.FileTypeManager; +//import com.intellij.openapi.project.Project; +//import com.intellij.openapi.ui.DialogWrapper; +//import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension; +//import com.vladsch.flexmark.ext.tables.TablesExtension; +//import com.vladsch.flexmark.ext.toc.TocExtension; +//import com.vladsch.flexmark.ext.wikilink.WikiLinkExtension; +//import com.vladsch.flexmark.html.HtmlRenderer; +//import com.vladsch.flexmark.parser.Parser; +//import com.vladsch.flexmark.util.ast.Node; +//import com.vladsch.flexmark.util.data.MutableDataSet; +//import lombok.Getter; +// +//import javax.swing.*; +//import java.awt.*; +//import java.awt.datatransfer.Clipboard; +//import java.awt.datatransfer.StringSelection; +//import java.io.BufferedWriter; +//import java.io.File; +//import java.io.FileWriter; +//import java.io.IOException; +//import java.util.Arrays; +// +///** +// * @author goodjava@qq.com +// * @author caobaoyu +// * @date 2023/7/13 +// * 一个md编辑器的dialog +// */ +//public class MarkdownDialog extends DialogWrapper { +// private Project project; +// private JButton saveButton; +// private JButton copyButton; +// private Editor editor; +// private JFrame frame; +// @Getter +// private DialogResult dialogResult = new DialogResult(); +// +// +// public MarkdownDialog(Project project) { +// super(true); +// this.project = project; +// init(); +// setTitle("Athena Markdown Editor"); +// editor = createEditor(project); +// createButtons(); +// } +// +// @Override +// public void show() { +// if (editor != null) { +// JPanel editorPanel = new JPanel(new BorderLayout()); +// editorPanel.add(editor.getComponent(), BorderLayout.CENTER); +// editorPanel.setPreferredSize(new Dimension(800, 600)); +// // 添加Markdown预览 +// JEditorPane previewPane = new JEditorPane(); +// previewPane.setEditable(false); +// previewPane.setContentType("text/html"); +// JScrollPane previewScrollPane = new JScrollPane(previewPane); +// previewScrollPane.setPreferredSize(new Dimension(400, 600)); +// JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, editorPanel, previewScrollPane); +// splitPane.setResizeWeight(0.5); +// splitPane.setOneTouchExpandable(true); +// splitPane.setDividerSize(2); // 设置分隔条的宽度 +// +// JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); +// buttonPanel.add(copyButton); +// buttonPanel.add(saveButton); +// +// frame = new JFrame("Markdown Editor"); +// frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); +// frame.getContentPane().add(splitPane, BorderLayout.CENTER); +// frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH); +// frame.pack(); +// frame.setVisible(true); +// // 更新Markdown预览 +// editor.getDocument().addDocumentListener(new DocumentListener() { +// @Override +// public void documentChanged(DocumentEvent event) { +// ApplicationManager.getApplication().runReadAction(() -> { +// String markdown = event.getDocument().getText(); +// MutableDataSet options = new MutableDataSet(); +// options.set(Parser.EXTENSIONS, Arrays.asList( +// TablesExtension.create(), +// TocExtension.create(), +// StrikethroughExtension.create(), +// WikiLinkExtension.create() +// )); +// Parser parser = Parser.builder(options).build(); +// Node document = parser.parse(markdown); +// HtmlRenderer renderer = HtmlRenderer.builder(options).build(); +// String html = renderer.render(document); +// previewPane.setText(html); +// }); +// } +// +// +// +// +// }); +// } +// } +// +// @Override +// protected JComponent createCenterPanel() { +// return new JPanel(new FlowLayout(FlowLayout.RIGHT)); +// } +// +// private Editor createEditor(Project project) { +// EditorFactory editorFactory = EditorFactory.getInstance(); +// Document document = EditorFactory.getInstance().createDocument("# Hello world"); +// final FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension("md"); +// Editor editor = editorFactory.createEditor(document, project, fileType, false); +// editor.getSettings().setLineNumbersShown(true); +// editor.getSettings().setFoldingOutlineShown(true); +// editor.getSettings().setAutoCodeFoldingEnabled(true); +// editor.getSettings().setAdditionalLinesCount(1); +// editor.getSettings().setAdditionalColumnsCount(1); +// editor.getSettings().setRightMarginShown(true); +// editor.getSettings().setRightMargin(80); +// editor.getSettings().setCaretRowShown(true); +// editor.getSettings().setUseSoftWraps(true); +// editor.getSettings().setSoftMargins(Lists.newArrayList(80)); +// editor.getSettings().setTabSize(4); +// editor.getSettings().setUseTabCharacter(false); +// +// return editor; +// } +// +// +// private void createButtons() { +// saveButton = new JButton("Save"); +// copyButton = new JButton("Copy"); +// +// saveButton.addActionListener(e -> onSaveButtonClick()); +// copyButton.addActionListener(e -> onCopyButtonClick()); +// } +// +// private void onSaveButtonClick() { +// JPanel panel = new JPanel(); +// String fileName = JOptionPane.showInputDialog(panel, "Enter file name:"); +// if (fileName != null && !fileName.trim().isEmpty()) { +// try { +// String path = project.getBaseDir().getPath() + "/" + fileName + ".md"; +// File file = new File(path); +// BufferedWriter writer = new BufferedWriter(new FileWriter(file)); +// String markdownContent = getMarkdownContent(); +// writer.write(markdownContent); +// writer.close(); +// putInfo(markdownContent); +// close(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// } +// +// private void onCopyButtonClick() { +// String markdownContent = getMarkdownContent(); +// if (!markdownContent.isEmpty()) { +// StringSelection selection = new StringSelection(markdownContent); +// Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); +// clipboard.setContents(selection, null); +// putInfo(markdownContent); +// close(); +// } +// +// } +// +// private String getMarkdownContent() { +// Editor editor = this.editor; +// if (editor != null) { +// Document document = editor.getDocument(); +// return document.getText(); +// } +// return ""; +// } +// +// public void close() { +// SwingUtilities.invokeLater(() -> { +// frame.dispose(); +// this.dispose(); +// }); +// } +// +// public void putInfo(String msg) { +// this.dialogResult.getData().put("text", msg); +// } +// +//} +// +// +// diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/ParamTableDialog.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/ParamTableDialog.java similarity index 87% rename from athena-all/src/main/java/run/mone/m78/ip/dialog/ParamTableDialog.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/ParamTableDialog.java index 22eff8871..1ef459f15 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/dialog/ParamTableDialog.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/ParamTableDialog.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.dialog; +package com.xiaomi.youpin.tesla.ip.dialog; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -8,16 +8,17 @@ import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.table.JBTable; -import run.mone.m78.ip.bo.ValueInfo; -import run.mone.m78.ip.bo.prompt.PromptParamType; -import run.mone.m78.ip.bo.ParamDialogReq; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.bo.prompt.PromptParam; -import run.mone.m78.ip.util.EditorUtils; -import run.mone.m78.ip.util.FileUtils; -import run.mone.m78.ip.util.ResourceUtils; -import run.mone.m78.ip.util.ScreenSizeUtils; +import com.xiaomi.youpin.tesla.ip.bo.ParamDialogReq; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.ValueInfo; +import com.xiaomi.youpin.tesla.ip.bo.prompt.PromptParam; +import com.xiaomi.youpin.tesla.ip.bo.prompt.PromptParamType; +import com.xiaomi.youpin.tesla.ip.util.EditorUtils; +import com.xiaomi.youpin.tesla.ip.util.FileUtils; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; +import com.xiaomi.youpin.tesla.ip.util.ScreenSizeUtils; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -80,7 +81,6 @@ public ParamTableDialog(ParamDialogReq req, @Nullable Project project, Map classList = ClassFinder.findClassList(project, type, name, moduleName); - classList.add(ClassInfo.builder().className("New").build()); + if (this.newClass) { + //class 支持new出来 + classList.add(ClassInfo.builder().className("New").build()); + } changeListModel(classList, "Class"); tabbedPane.setSelectedIndex(1); } if (selectedTab.equals("Class")) { if (req.getCmd().equals("test") || req.getCmd().equals("docean_controller")) { - String clazz = this.listMap.get("Class").getSelectedValue().getName(); + JBList list = this.listMap.get("Class"); + if (null == list || list.isEmpty()) { + return; + } + String clazz = list.getSelectedValue().getName(); this.result.getData().put("class", clazz); - PsiClass psiClass = CodeService.getPsiClass(project, context.getModule(), clazz); + //得用选中的selectModule,不然找不到class + PsiClass psiClass = CodeService.getPsiClass(project, ProjectUtils.getModuleWithName(project, selectModuleName), clazz); List methodList = new ArrayList<>(); if (null != psiClass) { + //查找所有public方法 methodList.addAll(CodeService.methods(psiClass).stream().map(it -> { MethodInfo mi = new MethodInfo(it); return mi; diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/SelectModuleDialog.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/SelectModuleDialog.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/dialog/SelectModuleDialog.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/SelectModuleDialog.java index 239af2565..3901cd908 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/dialog/SelectModuleDialog.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/SelectModuleDialog.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.dialog; +package com.xiaomi.youpin.tesla.ip.dialog; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; diff --git a/athena-all/src/main/java/run/mone/m78/ip/dialog/bo/CellValue.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/bo/CellValue.java similarity index 87% rename from athena-all/src/main/java/run/mone/m78/ip/dialog/bo/CellValue.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/bo/CellValue.java index dc30a4d99..db6220cb7 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/dialog/bo/CellValue.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/dialog/bo/CellValue.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.dialog.bo; +package com.xiaomi.youpin.tesla.ip.dialog.bo; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/enums/InvokePromptEnums.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/enums/InvokePromptEnums.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/enums/InvokePromptEnums.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/enums/InvokePromptEnums.java index 870bfda9e..e577c7d50 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/enums/InvokePromptEnums.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/enums/InvokePromptEnums.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.enums; +package com.xiaomi.youpin.tesla.ip.enums; import lombok.Getter; diff --git a/athena-all/src/main/java/run/mone/m78/ip/enums/ZTagEnums.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/enums/ZTagEnums.java similarity index 93% rename from athena-all/src/main/java/run/mone/m78/ip/enums/ZTagEnums.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/enums/ZTagEnums.java index e7c2cb864..3dac14fef 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/enums/ZTagEnums.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/enums/ZTagEnums.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.enums; +package com.xiaomi.youpin.tesla.ip.enums; import lombok.Getter; diff --git a/athena-all/src/main/java/run/mone/m78/ip/enums/ZTypeEnums.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/enums/ZTypeEnums.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/enums/ZTypeEnums.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/enums/ZTypeEnums.java index 1e813b132..838048ebb 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/enums/ZTypeEnums.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/enums/ZTypeEnums.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.enums; +package com.xiaomi.youpin.tesla.ip.enums; /** * @author caobaoyu diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/framework/flex/Flex.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/framework/flex/Flex.java new file mode 100644 index 000000000..1d041cae5 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/framework/flex/Flex.java @@ -0,0 +1,72 @@ +package com.xiaomi.youpin.tesla.ip.framework.flex; + +import com.intellij.psi.*; +import org.apache.commons.lang3.tuple.Pair; + +/** + * @author goodjava@qq.com + * @date 2024/1/29 13:53 + *

+ * 对mybatis flex 框架的一个适配 + */ +public class Flex { + + //获取ServiceImpl中的第二个泛型(也就是数据库中对应的类) + public static String findAndProcessServiceImplWithGeneric(PsiClass psiClass) { + PsiReferenceList extendsList = psiClass.getExtendsList(); + if (extendsList != null) { + for (PsiJavaCodeReferenceElement referenceElement : extendsList.getReferenceElements()) { + PsiClass superClass = (PsiClass) referenceElement.resolve(); + if (superClass != null && "ServiceImpl".equals(superClass.getName())) { + // 获取泛型参数 + PsiReferenceParameterList parameterList = referenceElement.getParameterList(); + if (parameterList != null) { + PsiType[] typeArguments = parameterList.getTypeArguments(); + if (typeArguments.length == 2) { + PsiType secondTypeArgument = typeArguments[1]; + if (secondTypeArgument instanceof PsiClassType) { + PsiClassType classType = (PsiClassType) secondTypeArgument; + PsiClass pc = classType.resolve(); + if (pc != null) { + return pc.getText(); + } + } + } + } + } + } + } + return ""; + } + + + //public interface E extends BaseMapper (获取到L) + public static Pair getBaseMapperGenericTypeNameAndText(PsiClass psiClass) { + PsiReferenceList extendsList = psiClass.getExtendsList(); + if (extendsList != null) { + for (PsiJavaCodeReferenceElement referenceElement : extendsList.getReferenceElements()) { + PsiElement resolved = referenceElement.resolve(); + if (resolved instanceof PsiClass) { + PsiClass baseMapperInterface = (PsiClass) resolved; + // 检查是否是 BaseMapper 接口 + if ("BaseMapper".equals(baseMapperInterface.getName())) { + // 获取 BaseMapper 接口的泛型参数 + PsiType[] typeArguments = referenceElement.getTypeParameters(); + if (typeArguments.length == 1) { + PsiType typeArgument = typeArguments[0]; + if (typeArgument instanceof PsiClassType) { + PsiClassType classTypeArgument = (PsiClassType) typeArgument; + PsiClass poClass = classTypeArgument.resolve(); + if (poClass != null) { + return Pair.of(poClass.getQualifiedName(), poClass.getText()); + } + } + } + } + } + } + } + return Pair.of("", ""); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/generator/ClassGenerator.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/ClassGenerator.java similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/generator/ClassGenerator.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/ClassGenerator.java index 85a51a6e7..0116496d1 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/generator/ClassGenerator.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/ClassGenerator.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package run.mone.m78.ip.generator; +package com.xiaomi.youpin.tesla.ip.generator; -import run.mone.m78.ip.common.FileUtils; +import com.xiaomi.youpin.tesla.ip.common.FileUtils; import java.io.File; import java.util.Map; diff --git a/athena-all/src/main/java/run/mone/m78/ip/generator/DirectoryGenerator.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/DirectoryGenerator.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/generator/DirectoryGenerator.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/DirectoryGenerator.java index 0926d1bb1..96cb2398f 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/generator/DirectoryGenerator.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/DirectoryGenerator.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package run.mone.m78.ip.generator; +package com.xiaomi.youpin.tesla.ip.generator; -import run.mone.m78.ip.common.FileUtils; +import com.xiaomi.youpin.tesla.ip.common.FileUtils; import java.io.File; diff --git a/athena-all/src/main/java/run/mone/m78/ip/generator/FileGenerator.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/FileGenerator.java similarity index 91% rename from athena-all/src/main/java/run/mone/m78/ip/generator/FileGenerator.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/FileGenerator.java index c61fe7994..991a073f5 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/generator/FileGenerator.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/FileGenerator.java @@ -14,11 +14,12 @@ * limitations under the License. */ -package run.mone.m78.ip.generator; +package com.xiaomi.youpin.tesla.ip.generator; -import run.mone.m78.ip.common.FileUtils; +import com.xiaomi.youpin.tesla.ip.common.FileUtils; import java.io.File; +import java.util.HashMap; import java.util.Map; /** diff --git a/athena-all/src/main/java/run/mone/m78/ip/generator/PackageGenerator.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/PackageGenerator.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/generator/PackageGenerator.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/PackageGenerator.java index 1f4bc4234..bb20a6d95 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/generator/PackageGenerator.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/PackageGenerator.java @@ -14,9 +14,12 @@ * limitations under the License. */ -package run.mone.m78.ip.generator; +package com.xiaomi.youpin.tesla.ip.generator; -import run.mone.m78.ip.common.FileUtils; +import com.xiaomi.youpin.tesla.ip.common.FileUtils; + +import java.util.HashMap; +import java.util.Map; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/m78/ip/generator/PomGenerator.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/PomGenerator.java similarity index 93% rename from athena-all/src/main/java/run/mone/m78/ip/generator/PomGenerator.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/PomGenerator.java index 45a82b968..f99ee4f0e 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/generator/PomGenerator.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/generator/PomGenerator.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package run.mone.m78.ip.generator; +package com.xiaomi.youpin.tesla.ip.generator; -import run.mone.m78.ip.common.FileUtils; +import com.xiaomi.youpin.tesla.ip.common.FileUtils; import java.io.File; import java.util.Map; diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/ChromeMessageRouterHandler.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/ChromeMessageRouterHandler.java similarity index 57% rename from athena-all/src/main/java/run/mone/m78/ip/listener/ChromeMessageRouterHandler.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/ChromeMessageRouterHandler.java index 8a5f90044..5bfd910ca 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/listener/ChromeMessageRouterHandler.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/ChromeMessageRouterHandler.java @@ -14,54 +14,47 @@ * limitations under the License. */ -package run.mone.m78.ip.listener; +package com.xiaomi.youpin.tesla.ip.listener; -import cn.hutool.core.bean.BeanUtil; -import com.google.common.base.Splitter; import com.google.common.collect.Maps; import com.google.gson.Gson; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.newvfs.RefreshQueue; +import com.xiaomi.youpin.tesla.ip.bo.Action; +import com.xiaomi.youpin.tesla.ip.bo.AiCodePromptRes; +import com.xiaomi.youpin.tesla.ip.bo.AiCodeRes; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.ProjectModuleInfo; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.ServerInfo; +import com.xiaomi.youpin.tesla.ip.common.ConfigCenter; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.JavaClassUtils; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.enums.InvokePromptEnums; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.GuideService; +import com.xiaomi.youpin.tesla.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.util.ProjectUtils; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; +import com.xiaomi.youpin.tesla.ip.util.UltramanConsole; import lombok.extern.slf4j.Slf4j; import org.apache.commons.compress.utils.Lists; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.mutable.Mutable; -import org.apache.commons.lang3.mutable.MutableInt; -import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.tuple.Pair; import org.cef.browser.CefBrowser; import org.cef.browser.CefFrame; import org.cef.callback.CefQueryCallback; import org.cef.handler.CefMessageRouterHandlerAdapter; -import org.jetbrains.annotations.Nullable; -import run.mone.m78.ip.bo.*; -import run.mone.m78.ip.bo.z.EmbeddingStatus; -import run.mone.m78.ip.common.*; -import run.mone.m78.ip.enums.InvokePromptEnums; -import run.mone.m78.ip.service.CodeService; -import run.mone.m78.ip.service.PromptService; -import run.mone.m78.ip.service.RobotService; -import run.mone.m78.ip.service.ScriptService; -import run.mone.m78.ip.ui.VersionUi; -import run.mone.m78.ip.util.LabelUtils; -import run.mone.m78.ip.util.ProjectUtils; -import run.mone.m78.ip.util.ResourceUtils; -import run.mone.m78.ip.util.UltramanConsole; import run.mone.ultraman.AthenaContext; -import run.mone.ultraman.bo.CodeReq; -import run.mone.ultraman.bo.Version; +import run.mone.ultraman.common.CodeUtils; import run.mone.ultraman.common.SafeRun; -import run.mone.ultraman.service.AthenaCodeService; -import run.mone.ultraman.service.ModuleService; -import run.mone.ultraman.state.ProjectFsmManager; -import java.io.File; import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; @@ -125,12 +118,15 @@ public boolean onQuery(CefBrowser browser, CefFrame frame, long query_id, String return true; } + // 从右侧聊天框插入代码到左侧代码编辑区 if (req.getCmd().equals("idea_insert_code")) { log.info("idea insert code"); String code = req.getData().get("code"); ApplicationManager.getApplication().invokeLater(() -> { CodeService.insertCode(project, code); }); + // 代码统计 + CodeUtils.uploadCodeGenInfo(Action.INSERT_CODE_FROM_CHAT.getCode(), code, "", project); } //调用miapi 这里需要拿到用户的key @@ -145,6 +141,10 @@ public boolean onQuery(CefBrowser browser, CefFrame frame, long query_id, String res = key; } + if (req.getCmd().equals("user")) { + res = AthenaContext.ins().getUserName(); + } + //获取http服务器信息和一些ide信息 if (req.getCmd().equals("server_info")) { res = this.getServerInfo(req); @@ -191,9 +191,9 @@ public boolean onQuery(CefBrowser browser, CefFrame frame, long query_id, String res = gson.toJson(ConfigCenter.getGuide()); } - //ai导航信息(上传代码的调用也再这里) + //ai导航信息(上传代码的调用也再这里):?就能开始调用的服务,主要用来测试 if (req.getCmd().equals("ai_guide")) { - res = this.aiGuide(req); + res = GuideService.aiGuide(req, this.project); } @@ -352,196 +352,6 @@ private String getAiCodePrompt() { return sb.toString(); } - /** - * AI引导方法,根据请求参数中的问题,获取相应的提示信息列表 - * - * @param req 请求参数对象,包含问题信息 - * @return 返回提示信息列表的JSON字符串 - */ - private String aiGuide(Req req) { - AiCodeRes res = new AiCodeRes(); - String question = req.getData().get("question"); - if (question.equals("flush")) { - Prompt.flush(); - res.setMsg("flush success"); - return gson.toJson(res); - } - - if (question.startsWith("invoke_code:")) { - List list = Splitter.on(":").splitToList(question); - if (list.size() == 4) { - String codeName = list.get(1); - String method = list.get(2); - String param = list.get(3); - Object codeRes = ScriptService.ins().invoke(ScriptService.getScript(codeName), method, Maps.newHashMap(), param); - res.setMsg("invoke code success:" + codeRes); - } else { - res.setMsg(list + " list size != 4"); - } - return gson.toJson(res); - } - - if (question.startsWith("model")) { - List list = Splitter.on(":").splitToList(question); - if (list.size() == 2) { - AthenaContext.ins().setGptModel(list.get(1)); - res.setMsg("set model success model:" + list.get(1)); - } - return gson.toJson(res); - } - - if (question.startsWith("aidebug")) { - List list = Splitter.on(":").splitToList(question); - if (list.size() == 2) { - AthenaContext.ins().setDebugAiProxy(Boolean.valueOf(list.get(1))); - res.setMsg("ai debug:" + list.get(1)); - } - return gson.toJson(res); - } - - if (question.equals("refreshconfig")) { - ResourceUtils.getAthenaConfig(this.project, true); - res.setMsg("refresh config success"); - return gson.toJson(res); - } - - //获取作者信息 - if (question.equals("author")) { - return author(res); - } - - if (question.startsWith("troubleshoot")) { - RobotService.troubleshoot(null, RobotReq.builder().project(this.project).param(question).build()); - return ""; - } - - //获取embedding 信息 - if (question.equals("embedding_status")) { - return embeddingStatus(req, res); - } - - //打开配置 - if (question.equals("config")) { - ApplicationManager.getApplication().invokeLater(() -> LabelUtils.showLabelConfigUi(this.project)); - res.setMsg("show config success"); - return gson.toJson(res); - } - - if (question.equals("collected")) { - res.setMsg(" "); - res.setPromptInfoList(buildAiCodePromptRes(Prompt.getCollected())); - return gson.toJson(res); - } - - if (question.equals("debug")) { - res.setMsg(new Version().toString()); - return gson.toJson(res); - } - - //刷新业务代码到知识库 - if (question.equals("flush_biz")) { - return flushBizCode(req, res); - } - - if (question.equals("class_len")) { - return getClassLen(res); - } - - //停止状态机 - if (question.equals("stop")) { - ProjectFsmManager.stop(project.getName()); - res.setMsg("退出状态机"); - return gson.toJson(res); - } - - //查询状态机状态 - if (question.equals("state")) { - String state = ProjectFsmManager.state(project.getName()); - res.setMsg("state:" + state); - return gson.toJson(res); - } - - AiCodeRes cache = ConfigCenter.build(question); - if (null == cache) { - res.setMsg(Message.unsupportedCommand); - return gson.toJson(res); - } - res.setMsg(cache.getMsg()); - if (!"help".equals(question)) { - List promptRes = Lists.newArrayList(); - List promptList = Prompt.getPromptInfoByTag(cache.getTagName()); - promptRes.addAll(cache.getPromptInfoList()); - promptRes.addAll(buildAiCodePromptRes(promptList)); - res.setPromptInfoList(promptRes); - } else { - res.setPromptInfoList(cache.getPromptInfoList()); - } - return gson.toJson(res); - } - - private String embeddingStatus(Req req, AiCodeRes res) { - String scope = req.getData().getOrDefault("scope", "project"); - CodeReq.CodeReqBuilder builder = CodeReq.builder(); - builder.projectName(this.project.getName()); - if (!scope.equals("project")) { - builder.moduleName(getModule(req.getData().get("module")).getName()); - } - EmbeddingStatus status = AthenaCodeService.embeddingStatus(builder.build()); - String msg = scope.equals("project") ? ("project_" + req.getData().get("project")) : ("module_" + req.getData().get("module")); - res.setMsg(gson.toJson(status) + ":" + msg); - return gson.toJson(res); - } - - //刷新业务代码到知识库 - private String flushBizCode(Req req, AiCodeRes res) { - String moduleName = req.getData().get("module"); - String scope = req.getData().get("scope"); - ApplicationManager.getApplication().invokeLater(() -> { - if ("project".equals(scope)) { - //Refresh all modules. - List list = ProjectUtils.listAllModules(this.project).stream().filter(it -> !it.equals(req.getData().get("project"))).collect(Collectors.toList()); - list.stream().forEach(it -> ModuleService.uploadModelText(this.project, getModule(it))); - } else { - ModuleService.uploadModelText(this.project, getModule(moduleName)); - } - }); - res.setMsg("flush biz success"); - return gson.toJson(res); - } - - //获取当前打开类的长度 - private String getClassLen(AiCodeRes res) { - MutableInt num = new MutableInt(); - ApplicationManager.getApplication().invokeAndWait(() -> { - String text = CodeService.getClassText(this.project); - num.setValue(text.length()); - }); - res.setMsg(String.valueOf(num.getValue())); - return gson.toJson(res); - } - - //获取作者信息 - private String author(AiCodeRes res) { - ApplicationManager.getApplication().invokeLater(() -> { - VersionUi versionUi = new VersionUi(); - versionUi.show(); - }); - res.setMsg(new Version().toString()); - return gson.toJson(res); - } - - @Nullable - private Module getModule(String moduleName) { - if (StringUtils.isEmpty(moduleName)) { - Mutable mutable = new MutableObject<>(); - ApplicationManager.getApplication().invokeAndWait(() -> { - mutable.setValue(ProjectUtils.getCurrentModule(this.project)); - }); - return mutable.getValue(); - } else { - return ProjectUtils.getModuleWithName(this.project, moduleName); - } - } /** * 获取项目信息并以JSON格式返回。 @@ -563,21 +373,4 @@ public void onQueryCanceled(CefBrowser browser, CefFrame frame, long query_id) { } - private void refreshProject(String targetExtractionDir) { - VirtualFile targetFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(targetExtractionDir)); - RefreshQueue.getInstance().refresh(false, true, null, targetFile); - } - - private List buildAiCodePromptRes(List promptInfoList) { - List list = promptInfoList.stream().filter(p -> p.getTags().stream().anyMatch(tag -> tag.getName().equals("plugin"))).map(promptInfo -> { - AiCodePromptRes promptRes = new AiCodePromptRes(); - BeanUtil.copyProperties(promptInfo, promptRes); - promptRes.setType("cmd"); - promptRes.setShowDialog(promptInfo.getLabels().getOrDefault("showDialog", "false")); - return promptRes; - }).collect(Collectors.toList()); - return list; - } - - } diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/DevToolsDialog.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/DevToolsDialog.java similarity index 97% rename from athena-all/src/main/java/run/mone/m78/ip/listener/DevToolsDialog.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/DevToolsDialog.java index da292ec0b..1d564377e 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/listener/DevToolsDialog.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/DevToolsDialog.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.listener; +package com.xiaomi.youpin.tesla.ip.listener; import org.cef.browser.CefBrowser; diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/LocalHandler.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/LocalHandler.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/listener/LocalHandler.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/LocalHandler.java index c67b1cbcd..7a0ced87c 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/listener/LocalHandler.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/LocalHandler.java @@ -1,14 +1,14 @@ -package run.mone.m78.ip.listener; +package com.xiaomi.youpin.tesla.ip.listener; import com.intellij.openapi.project.Project; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.LocalReq; +import com.xiaomi.youpin.tesla.ip.bo.robot.*; +import com.xiaomi.youpin.tesla.ip.service.LocalAiService; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; -import run.mone.m78.ip.bo.chatgpt.LocalReq; -import run.mone.m78.ip.bo.robot.*; -import run.mone.m78.ip.service.LocalAiService; import run.mone.ultraman.AthenaContext; import run.mone.ultraman.bo.ClientData; import run.mone.ultraman.common.GsonUtils; diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/MenuHandler.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/MenuHandler.java similarity index 97% rename from athena-all/src/main/java/run/mone/m78/ip/listener/MenuHandler.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/MenuHandler.java index dc65e5891..0abec178e 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/listener/MenuHandler.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/MenuHandler.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.listener; +package com.xiaomi.youpin.tesla.ip.listener; import org.cef.browser.CefBrowser; import org.cef.browser.CefFrame; diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/OpenAiListener.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/OpenAiListener.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/listener/OpenAiListener.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/OpenAiListener.java index 0acdec9fc..e77b3693c 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/listener/OpenAiListener.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/OpenAiListener.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.listener; +package com.xiaomi.youpin.tesla.ip.listener; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/PromptHandler.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/PromptHandler.java new file mode 100644 index 000000000..36b25d9fa --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/PromptHandler.java @@ -0,0 +1,127 @@ +package com.xiaomi.youpin.tesla.ip.listener; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.SelectionModel; +import com.intellij.openapi.project.Project; +import com.xiaomi.youpin.tesla.ip.bo.robot.AiChatMessage; +import com.xiaomi.youpin.tesla.ip.bo.robot.ProjectAiMessageManager; +import com.xiaomi.youpin.tesla.ip.bo.robot.Role; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.LocalAiService; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.MutableObject; +import run.mone.ultraman.manager.ConsoleViewManager; +import run.mone.ultraman.service.AiCodeService; +import run.mone.ultraman.state.ProjectFsmManager; + +import java.util.UUID; + +/** + * @author goodjava@qq.com + * @date 2023/12/10 16:01 + */ +public class PromptHandler { + + + //修改用户的问题 + public static String handler(Project project, Req req) { + if (req.getCmd().equals("modifyPrompt")) { + String prompt = req.getData().get("prompt"); + MutableObject r = new MutableObject<>(); + r.setValue(prompt); + changePrompt(project, prompt, r, req); + return r.getValue(); + } + return ""; + } + + //根据给定的提示更改提示信息,并在需要的情况下生成代码 + private static void changePrompt(Project project, String prompt, MutableObject r, Req req) { + //如果有长问答,长问答的优先级要更高 + if (!prompt.startsWith("?")) { + boolean process = ProjectFsmManager.processMsg(project.getName(), prompt); + if (process) { + r.setValue("?$$$" + prompt); + return; + } + } else { + r.setValue(prompt); + return; + } + + //机器人指令 + if (prompt.startsWith(">>")) { + String cmd = prompt.substring(2); + VisionHandler.callBot(project, cmd); + r.setValue("?$$$" + cmd); + return; + } + + + //直接生成业务代码 + if (prompt.startsWith("//")) { + removeSelection(project); + AiCodeService.generateBizCode(req.getData().get("scope"), project, prompt); + String message = prompt.substring(2); + ProjectAiMessageManager.getInstance().appendMsg(project, AiChatMessage.builder().id(UUID.randomUUID().toString()).role(Role.user).message(message).data(message).build()); + //返回这种协议开头的,前端就不在问chatgpt了,只做显示 + r.setValue("?$$$" + message); + return; + } + + + ApplicationManager.getApplication().invokeAndWait(() -> { + Editor editor = CodeService.getEditor(project); + if (null != editor) { + r.setValue(prompt); + + //直接本地问chatgpt + if (prompt.startsWith("::")) { + removeSelection(project); + String newPrompt = prompt.substring(2); + LocalAiService.localCall(project, newPrompt); + //返回这种协议开头的,前端就不在问chatgpt了,只做显示 + r.setValue("?$$$" + newPrompt); + } + + + if (ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_SELECT_TEXT, "true").equals("true")) { + //选中编辑器中的文本 + if (CodeService.isTextSelected(editor)) { + SelectionModel selectionModel = editor.getSelectionModel(); + String selectedText = selectionModel.getSelectedText(); + StringBuilder sb = new StringBuilder(prompt); + sb.append("\n```\n" + selectedText + "\n```\n"); + r.setValue(sb.toString()); + } + + //选中Console中的文本 + String text = ConsoleViewManager.getSelectedText(project); + if (StringUtils.isNotEmpty(text)) { + StringBuilder sb = new StringBuilder(prompt); + sb.append("\n```\n" + text + "\n```\n"); + r.setValue(sb.toString()); + } + } + + } + }); + + + } + + + //移除选择 + private static void removeSelection(Project project) { + ApplicationManager.getApplication().invokeAndWait(() -> { + Editor editor = CodeService.getEditor(project); + if (null != editor) { + editor.getSelectionModel().removeSelection(); + } + }); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/Req.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/Req.java similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/listener/Req.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/Req.java index 216d9e3df..aadeb79d3 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/listener/Req.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/Req.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.listener; +package com.xiaomi.youpin.tesla.ip.listener; import java.util.Map; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/RequestHandler.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/RequestHandler.java new file mode 100644 index 000000000..fad9220c9 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/RequestHandler.java @@ -0,0 +1,21 @@ +package com.xiaomi.youpin.tesla.ip.listener; + +import org.cef.browser.CefBrowser; +import org.cef.handler.CefRequestHandlerAdapter; + +/** + * @author goodjava@qq.com + * @date 2023/11/22 18:40 + */ +public class RequestHandler extends CefRequestHandlerAdapter { + + +// @Override +// public void onPermissionRequest(CefBrowser browser, String origin_url, int permissionType, boolean isMainFrame, PermissionCallback callback) { +// if (permissionType == CefRequestHandler.PERMISSIONTYPE_MEDIASTREAM_MIC || permissionType == CefRequestHandler.PERMISSIONTYPE_MEDIASTREAM_CAMERA) { +// callback.Continue(true); +// } else { +// callback.Continue(false); +// } +// } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/UltrmanTreeKeyAdapter.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/UltrmanTreeKeyAdapter.java similarity index 77% rename from athena-all/src/main/java/run/mone/m78/ip/listener/UltrmanTreeKeyAdapter.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/UltrmanTreeKeyAdapter.java index 031eebacc..c89037d8d 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/listener/UltrmanTreeKeyAdapter.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/UltrmanTreeKeyAdapter.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package run.mone.m78.ip.listener; +package com.xiaomi.youpin.tesla.ip.listener; import com.google.gson.Gson; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.project.Project; @@ -24,27 +25,27 @@ import com.intellij.ui.jcef.JBCefApp; import com.intellij.ui.jcef.JBCefBrowser; import com.intellij.ui.jcef.JBCefClient; -import run.mone.m78.ip.renderer.CustomIconRenderer; -import run.mone.m78.ip.util.ProjectUtils; -import run.mone.m78.ip.bo.SpiderUrl; -import run.mone.m78.ip.bo.TbTask; -import run.mone.m78.ip.common.ApiCall; -import run.mone.m78.ip.common.ConfigUtils; -import run.mone.m78.ip.service.SpiderService; -import run.mone.m78.ip.service.TaskService; -import run.mone.m78.ip.service.UserService; -import run.mone.m78.ip.util.FileUtils; -import run.mone.m78.ip.util.UltramanConsole; +import com.xiaomi.youpin.tesla.ip.bo.SpiderUrl; +import com.xiaomi.youpin.tesla.ip.bo.TbTask; +import com.xiaomi.youpin.tesla.ip.common.ApiCall; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.Safe; +import com.xiaomi.youpin.tesla.ip.renderer.CustomIconRenderer; +import com.xiaomi.youpin.tesla.ip.service.SpiderService; +import com.xiaomi.youpin.tesla.ip.service.TaskService; +import com.xiaomi.youpin.tesla.ip.service.UserService; +import com.xiaomi.youpin.tesla.ip.util.FileUtils; +import com.xiaomi.youpin.tesla.ip.util.ProjectUtils; +import com.xiaomi.youpin.tesla.ip.util.UltramanConsole; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.cef.CefClient; import org.cef.browser.CefBrowser; import org.cef.browser.CefFrame; import org.cef.browser.CefMessageRouter; -import org.cef.callback.CefContextMenuParams; -import org.cef.callback.CefMediaAccessCallback; -import org.cef.callback.CefMenuModel; -import org.cef.handler.CefContextMenuHandlerAdapter; -import org.cef.handler.CefLifeSpanHandlerAdapter; +import org.cef.callback.*; +import org.cef.handler.*; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; @@ -56,6 +57,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Collectors; @@ -123,6 +125,16 @@ public void loadMone(String apiUrl, String text) { return true; }); + if (System.getProperty("os.name").contains("Linux")) { + client.getCefClient().addDialogHandler((browser, mode, title, defaultFilePath, acceptFilters, callback) -> { + // TODO + String filePath = showFileChooserDialog(project); + acceptFilters.add(filePath); + callback.Continue(acceptFilters); + return true; + }); + } + client.addLifeSpanHandler(new CefLifeSpanHandlerAdapter() { @Override public boolean onBeforePopup(CefBrowser browser, CefFrame frame, String target_url, String target_frame_name) { @@ -269,4 +281,37 @@ private void setTreeModel(String name, List list, Function fun tree1.setCellRenderer(new CustomIconRenderer(name)); } + public String showFileChooserDialog(Project project) { + AtomicReference filePath = new AtomicReference<>(""); + ApplicationManager.getApplication().invokeAndWait(() -> { + FileChooserDescriptor fileChooserDescriptor = new FileChooserDescriptor(true, false, false, false, false, false); + fileChooserDescriptor.setTitle("选择文件"); + fileChooserDescriptor.setDescription("请选择一个图片"); + VirtualFile file = FileChooser.chooseFile(fileChooserDescriptor, project, null); + if (file != null) { + filePath.set(file.getCanonicalPath()); + } + }); + return filePath.get(); + } + + public static void forceRefresh(JBCefBrowser cefBrowser,String url) { + if (cefBrowser != null) { + // 通过重新加载当前URL来强制刷新浏览器 + String currentUrl = cefBrowser.getCefBrowser().getURL(); + if (StringUtils.isNotEmpty(url)) { + currentUrl = url; + } + cefBrowser.loadURL(currentUrl); + refreshWithDisableCache(cefBrowser); + log.info("Refresh with load on: {}", currentUrl); + } + } + + public static void refreshWithDisableCache(JBCefBrowser cefBrowser) { + Safe.run(()->{ + final CefBrowser[] devTools = {cefBrowser.getCefBrowser().getDevTools()}; + devTools[0].reloadIgnoreCache(); + }); + } } diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/VisionHandler.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/VisionHandler.java similarity index 59% rename from athena-all/src/main/java/run/mone/m78/ip/listener/VisionHandler.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/VisionHandler.java index cb5b07f68..7bf7cc770 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/listener/VisionHandler.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/listener/VisionHandler.java @@ -1,21 +1,24 @@ -package run.mone.m78.ip.listener; +package com.xiaomi.youpin.tesla.ip.listener; import cn.hutool.core.codec.Base64; import com.google.common.collect.ImmutableMap; +import com.google.gson.JsonObject; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import com.xiaomi.youpin.infra.rpc.Result; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.*; +import com.xiaomi.youpin.tesla.ip.common.ChromeUtils; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.service.LocalAiService; +import com.xiaomi.youpin.tesla.ip.service.M78Service; +import com.xiaomi.youpin.tesla.ip.service.PromptService; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.bo.chatgpt.*; -import run.mone.m78.ip.common.ChromeUtils; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.common.PromptType; -import run.mone.m78.ip.service.LocalAiService; -import run.mone.m78.ip.service.PromptService; import run.mone.ultraman.background.AthenaTask; import java.io.File; @@ -32,17 +35,20 @@ public class VisionHandler { public static String handler(Project project, Req req) { //传递录制的声音 if (req.getCmd().equals("sound")) { - return saveSound(project, req); +// return saveSound(project, req); + return saveSound2(project, req); } //播放声音 if (req.getCmd().equals("play sound")) { - return playSound2(project, req); +// return playSound2(project, req); + return playSound3(project, req); } //多模态,可以对图像提问 if (req.getCmd().equals("vision")) { - return vision(project, req); +// return vision(project, req); + return vision2(project, req); } return ""; } @@ -74,6 +80,25 @@ public void run(@NotNull ProgressIndicator indicator) { return res; } + private static String saveSound2(Project project, Req req) { + String soundInBase64 = req.getData().get("sound"); + String res = ""; + AthenaTask.start(new Task.Backgroundable(project, "speech to text", true) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("text", soundInBase64); + jsonObject.addProperty("format", "mp3"); + Result transRes = M78Service.speechToText2(jsonObject); + if (transRes.getCode() == 0) { + ChromeUtils.call(project.getName(), transRes.getData(), 0); + } + } + }); + res = "ok:" + soundInBase64.length(); + return res; + } + @NotNull private static String playSound2(Project project, Req req) { String res; @@ -91,6 +116,24 @@ public void run(@NotNull ProgressIndicator indicator) { return res; } + private static String playSound3(Project project, Req req) { + String res; + AthenaTask.start(new Task.Backgroundable(project, "text to speech", true) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("text", req.getData().get("input")); + Result result = M78Service.textToSpeech(jsonObject); + if (result.getCode() == 0) { + String s = new String(result.getData()); + ChromeUtils.call(project.getName(), s, 777); + } + } + }); + res = ""; + return res; + } + //多模态能力(可以识别图片) @NotNull private static String vision(Project project, Req req) { @@ -114,6 +157,19 @@ public void run(@NotNull ProgressIndicator indicator) { return res; } + private static String vision2(Project project, Req req) { + // 将req构建为m78格式的多模态ws请求 + JsonObject jsonReq = new JsonObject(); + jsonReq.addProperty("multimodal", 2); + jsonReq.addProperty("botId", 100307); + jsonReq.addProperty("topicId", 4090); + jsonReq.addProperty("input", req.getData().get("input")); + jsonReq.addProperty("mediaType", req.getData().get("mediaType")); + jsonReq.addProperty("postscript", req.getData().get("postscript")); + M78Service.imageHandle(project, jsonReq); + return "processing pic..."; + } + private static Pair playSound(Req req) { return LocalAiService.speech(SpeechReq.builder().input(req.getData().get("input")).build()); } diff --git a/athena-all/src/main/java/run/mone/m78/ip/renderer/CustomIconRenderer.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/renderer/CustomIconRenderer.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/renderer/CustomIconRenderer.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/renderer/CustomIconRenderer.java index cb3aa7f7e..582a975ec 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/renderer/CustomIconRenderer.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/renderer/CustomIconRenderer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.renderer; +package com.xiaomi.youpin.tesla.ip.renderer; import com.intellij.openapi.util.IconLoader; diff --git a/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributor.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/AthenaSearchEverywhereContributor.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributor.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/AthenaSearchEverywhereContributor.java index 4c504f2dd..053fe07f7 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributor.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/AthenaSearchEverywhereContributor.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.search; +package com.xiaomi.youpin.tesla.ip.search; import com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor; import com.intellij.openapi.module.Module; @@ -7,15 +7,15 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiMethod; import com.intellij.util.Processor; -import run.mone.m78.ip.bo.ElementInfo; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.common.PromptType; -import run.mone.m78.ip.service.CodeService; -import run.mone.m78.ip.service.PromptService; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.common.Const; -import run.mone.m78.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.bo.ElementInfo; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; import lombok.SneakyThrows; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributorFactory.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/AthenaSearchEverywhereContributorFactory.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributorFactory.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/AthenaSearchEverywhereContributorFactory.java index 322776cef..b464e80b5 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchEverywhereContributorFactory.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/AthenaSearchEverywhereContributorFactory.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.search; +package com.xiaomi.youpin.tesla.ip.search; import com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributor; import com.intellij.ide.actions.searcheverywhere.SearchEverywhereContributorFactory; diff --git a/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchInfo.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/AthenaSearchInfo.java similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchInfo.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/AthenaSearchInfo.java index 04ec19f11..3dafd0090 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/search/AthenaSearchInfo.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/AthenaSearchInfo.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.search; +package com.xiaomi.youpin.tesla.ip.search; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/m78/ip/search/MyChooseByNameContributor.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/MyChooseByNameContributor.java similarity index 98% rename from athena-all/src/main/java/run/mone/m78/ip/search/MyChooseByNameContributor.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/MyChooseByNameContributor.java index 14fe6670c..6e727bbd8 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/search/MyChooseByNameContributor.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/MyChooseByNameContributor.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.search; +package com.xiaomi.youpin.tesla.ip.search; import com.intellij.navigation.ChooseByNameContributor; import com.intellij.navigation.ItemPresentation; diff --git a/athena-all/src/main/java/run/mone/m78/ip/search/MyCustomNavigationItem.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/MyCustomNavigationItem.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/search/MyCustomNavigationItem.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/MyCustomNavigationItem.java index d2f29b12c..c1db18276 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/search/MyCustomNavigationItem.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/search/MyCustomNavigationItem.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.search; +package com.xiaomi.youpin.tesla.ip.search; import com.intellij.navigation.ItemPresentation; import com.intellij.navigation.NavigationItem; diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/AbstractService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/AbstractService.java similarity index 92% rename from athena-all/src/main/java/run/mone/m78/ip/service/AbstractService.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/AbstractService.java index aa64165d0..8a35396c2 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/AbstractService.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/AbstractService.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package run.mone.m78.ip.service; +package com.xiaomi.youpin.tesla.ip.service; import com.intellij.openapi.actionSystem.AnActionEvent; -import run.mone.m78.ip.common.Context; +import com.xiaomi.youpin.tesla.ip.common.Context; /** * @Author goodjava@qq.com diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/AiService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/AiService.java new file mode 100644 index 000000000..1cb822191 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/AiService.java @@ -0,0 +1,30 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import com.google.gson.JsonObject; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; + +/** + * @author goodjava@qq.com + * @date 2023/12/5 22:51 + */ +public class AiService { + + + //同时支持远程和本地的(本地的被限流的次数会更少) + public static JsonObject call(String req, long timeout, boolean vip, boolean jsonResult) { + if (LabelUtils.open(Const.OPEN_AI_TEST)) { + return LocalAiService.call(req, timeout); + } + return ProxyAiService.call(req, timeout, vip, jsonResult); + + } + + + public static JsonObject call(String req, long timeout, boolean vip) { + return call(req, timeout, vip, true); + } + + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/BotService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/BotService.java new file mode 100644 index 000000000..7b6506a66 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/BotService.java @@ -0,0 +1,356 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import com.google.common.base.Stopwatch; +import com.google.common.collect.ImmutableMap; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.xiaomi.youpin.tesla.ip.bo.*; +import com.xiaomi.youpin.tesla.ip.common.*; +import com.xiaomi.youpin.tesla.ip.service.consumer.BotMsgConsumer; +import com.xiaomi.youpin.tesla.ip.util.ActionUtils; +import com.xiaomi.youpin.tesla.ip.util.GitUtils; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; +import com.xiaomi.youpin.tesla.ip.util.TerminalUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.background.AthenaTask; +import run.mone.ultraman.bo.Version; +import run.mone.ultraman.common.CodeUtils; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.common.ImportCode; +import run.mone.ultraman.common.TestRunnerUtils; +import run.mone.ultraman.http.HttpClient; +import run.mone.ultraman.http.WsClient; +import run.mone.ultraman.listener.event.TaskEvent; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2024/6/5 23:03 + * 目前是Athena最核心的逻辑 + * 主要用来调用bot(调用m78平台) + * 分为同步调用和异步调用 + */ +@Slf4j +public class BotService { + + private static final String BOT_URL = "http://localhost/open-apis/ai-plugin-new/feature/router/probot/query"; + + //执行bot(支持流式调用,和直接json返回) + public static void executeBot(GenerateCodeReq req) { + PromptInfo promptInfo = req.getPromptInfo(); + if (null != promptInfo) { + Map labels = promptInfo.getLabels(); + if (isLabeldWithSteam(labels)) { + //调用流试服务(实现打字机效果),比如代码生成 + streamBotCall(req, labels); + } else { + //直接调用bot,返回json,比如:给方法从命名,一键提交代码 + directBotCall(req, labels); + } + // 执行bot之后上传插件统计信息。这块只统计非生成代码的行为。生成代码会在BotMsgConsumer中进行统计 + Action action = ActionUtils.getActionByReq(req); + if (Action.GENERATE_CODE != action) { + CodeUtils.uploadCodeGenInfo(action.getCode(), + req.getProjectName(), + req.getClassName(), + req.getPsiMethod() == null ? "" : req.getPsiMethod().getName()); + } + } + } + + private static boolean isLabeldWithSteam(Map labels) { + return labels.getOrDefault("stream", "false").equals("true"); + } + + private static void directBotCall(GenerateCodeReq req, Map labels) { + JsonObject jsonReq = new JsonObject(); + jsonReq.addProperty(Const.BOT_ID, labels.get("botId")); + + //如果是private_prompt = true 的bot,需要注意传一个params参数,这个参数实际是一个Map结构 + + //git push + if (handleGitPushInfo(req, jsonReq)) return; + + //修改方法名 + handleModifyMethodName(req, jsonReq); + + //bug fix(问题修复) + if (handleBugFix(req, labels, jsonReq)) return; + + handleGenerateCodeReqAndBotRes(req, jsonReq); + } + + private static void handleGenerateCodeReqAndBotRes(GenerateCodeReq req, JsonObject jsonReq) { + String botRes = null; + try { + botRes = callBot(req.getProject(), jsonReq); + } catch (Throwable e) { + log.warn("callBot error:{}", e.getMessage()); + return; + } + //处理结果 + handleGenerateCodeReqAndBotRes(req, botRes); + } + + private static boolean handleBugFix(GenerateCodeReq req, Map labels, JsonObject jsonReq) { + //bug fix(问题修复) + if (Action.BUG_FIX == ActionUtils.getActionByReq(req)) { + ApplicationManager.getApplication().invokeLater(() -> { + TestRunnerUtils.runTest(req.getProject(), req.getPsiMethod().getName(), pair -> { + //查问题需要行号 + Map params = ImmutableMap.of("method", pair.getKey(), "error", pair.getValue()); + jsonReq.add("params", GsonUtils.gson.toJsonTree(params)); + jsonReq.addProperty("input", ""); + //处理结果 + handleGenerateCodeReqAndBotRes(req, jsonReq); + }); + }); + return true; + } + return false; + } + + private static void handleModifyMethodName(GenerateCodeReq req, JsonObject jsonReq) { + if (Action.SMART_NAMING == ActionUtils.getActionByReq(req)) { + Map params = ImmutableMap.of("code", req.getMethodCode()); + jsonReq.add("params", GsonUtils.gson.toJsonTree(params)); + jsonReq.addProperty("input", ""); + } + } + + private static boolean handleGitPushInfo(GenerateCodeReq req, JsonObject jsonReq) { + if (Action.GIT_PUSH == ActionUtils.getActionByReq(req)) { + List list = GitUtils.getAffectedFileNames(req.getProject()); + String commitDiff = GitUtils.getCommitDiff(req.getProject()); + if (commitDiff.length() > 10000) { + // 太长了,截断下 + commitDiff = commitDiff.substring(0, 5000); + } + String currentBranch = GitUtils.getCurrentBranch(req.getProject()); + if (list.isEmpty()) { + log.info("getAffectedFileNames num:0"); + return true; + } + JsonObject input = new JsonObject(); + input.add("changedFiles", GsonUtils.gson.toJsonTree(list)); + input.addProperty("diff", commitDiff); + input.addProperty("branch", currentBranch); + jsonReq.addProperty("input", input.toString()); + } + return false; + } + + private static void handleGenerateCodeReqAndBotRes(GenerateCodeReq req, String botRes) { + switch (ActionUtils.getActionByReq(req)) { + //操作terminal + case GIT_PUSH: + TerminalUtils.executeTerminalCommand(req.getProject(), botRes); + break; + //给方法重命名 + case SMART_NAMING: + PsiMethodUtils.renameMethod(req.getProject(), req.getPsiMethod(), botRes); + break; + //bug fix + case BUG_FIX: + log.info("fix method:{}", botRes); + //替换这个方法的内容 + PsiMethodUtils.replacePsiMethod(req.getProject(), req.getPsiMethod(), botRes); + break; + } + } + + //这里会调用到m78:WebSocketHandler + private static void streamBotCall(GenerateCodeReq req, Map labels) { + String out = req.getPromptInfo().getLabels().getOrDefault("bot_out", "athena"); + WsClient wsClient = new WsClient(); + if (!Objects.isNull(req.getCountDownLatch())) { + wsClient.setLatch(req.getCountDownLatch()); + } + //for test +// wsClient.setUrl("ws://127.0.0.1:8077/ws/bot/abc"); + wsClient.setProjectName(req.getProject().getName()); + String id = UUID.randomUUID().toString(); + wsClient.setId(id); + + ImportCode importCode = new ImportCode(); + importCode.setProject(req.getProject()); + importCode.setEditor(req.getEditor()); + + Stopwatch sw = Stopwatch.createStarted(); + wsClient.init(getAiMessageConsumer(req, out, importCode, sw)); + JsonObject jsonReq = new JsonObject(); + jsonReq.addProperty(Const.BOT_ID, labels.get("botId")); + //ztoken(可以用来换取用户名) + jsonReq.addProperty(Const.TOKEN, ConfigUtils.getConfig().getzToken()); + + String input = ""; + switch (ActionUtils.getActionByReq(req)) { + case GENERATE_CODE: + //通过注释生成代码 + if (null != req.getParam().get(Const.GENERATE_CODE_COMMENT)) { + input = req.getParam().get(Const.GENERATE_CODE_COMMENT); + } else { + input = req.getCurrentLine(); + } + + if (req.getParam().containsKey("__code")) { + input = req.getParam().get("__code"); + } + //生成代码的时候有许多参数和上下文,靠这里拿到这些参数列表 + JsonObject params = generateParams(req, input); + input = ""; + jsonReq.add("params", params); + break; + case CHAT: + // 聊天 + input = req.getParam().get("chatContent"); + break; + case UNIT_TEST: + // 单元测试 + jsonReq.add("params", generateUnitTestParams(req)); + break; + case GENERATE_COMMENT: + case CODE_SUGGESTION: + //给代码添加注释, 代码建议 + if (StringUtils.isNotEmpty(req.getMethodCode())) { + input = req.getMethodCode(); + } else { + wsClient.getWs().close(1000, null); + return; + } + break; + } + jsonReq.addProperty("input", input); + jsonReq.addProperty("topicId", id); + // 添加version参数 + addVersionParam(jsonReq); + // 添加用户自定义model + setModel(req, jsonReq); + + wsClient.send(jsonReq); + } + + @NotNull + public static JsonObject generateParams(GenerateCodeReq req, String input) { + JsonObject params = new JsonObject(); + params.addProperty("code", input); + params.addProperty("class", req.getClassCode()); + + if (null == req.getInheritedMethods()) { +// NotificationCenter.notice(ErrorMessage.ERR_NOT_IN_CLASS_SCOPE, NotificationType.ERROR); +// throw new RuntimeException(ErrorMessage.ERR_NOT_IN_CLASS_SCOPE); + log.error(ErrorMessage.ERR_NOT_IN_CLASS_SCOPE); + } else { + params.addProperty("inheritedMethods", req.getInheritedMethods().stream().collect(Collectors.joining("\n\n\n"))); + } + params.addProperty("fqcn", req.getQualifiedName()); + //计算上下文(context) + updateParamsWithContext(req, params); + return params; + } + + @NotNull + public static JsonObject generateUnitTestParams(GenerateCodeReq req) { + JsonObject params = new JsonObject(); + params.addProperty("code", req.getParam().get("code")); + params.addProperty("testClassCode", req.getParam().get("testClassCode")); + return params; + } + + private static void updateParamsWithContext(GenerateCodeReq req, JsonObject params) { + Safe.run(() -> { + String context = getContextFromGenerateCodeReq(req); + params.addProperty("context", context); + }); + } + + //获取计算 + private static String getContextFromGenerateCodeReq(GenerateCodeReq req) { + AthenaTask athenaTask = PromptService.generateMethod(req, false); + athenaTask.getInitRunnable().run(); + athenaTask.initContexts(); + athenaTask.calculateAndOptimizeRequestSize(); + String context = athenaTask.getContext(); + return context; + } + + + @NotNull + private static Consumer getAiMessageConsumer(GenerateCodeReq req, String out, ImportCode importCode, Stopwatch sw) { + return new BotMsgConsumer(req, out, importCode, sw); + } + + + //直接调用bot,然后返回json,解析json结果 + public static String callBot(Project project, JsonObject jsonReq) { + String userName = ConfigUtils.getConfig().getNickName(); + jsonReq.addProperty("userName", userName); + jsonReq.addProperty("projectName", project.getName()); + jsonReq.addProperty(Const.TOKEN, ConfigUtils.getConfig().getzToken()); + // 添加version参数 + addVersionParam(jsonReq); + String param = jsonReq.toString(); + + //看起来很麻烦,是因为这个不一定在那个线程里,只能通过这种方式稳定的调用 + ApplicationManager.getApplication().getMessageBus().syncPublisher(TaskEvent.TOPIC).onEvent(TaskEvent.builder().message("begin").build()); + Stopwatch sw = Stopwatch.createStarted(); + String resStr = ""; + try { + String botUrl = ResourceUtils.getAthenaConfig().getOrDefault(Const.BOT_URL, ""); + if (StringUtils.isEmpty(botUrl)) { + botUrl = BOT_URL; + } + //for test +// http://127.0.0.1:8077/open-apis/v1/ai-plugin-new/feature/router/probot/query + resStr = HttpClient.callHttpServer(botUrl, "callBot", param, false, false, 20); + } finally { + ApplicationManager.getApplication().getMessageBus().syncPublisher(TaskEvent.TOPIC).onEvent(TaskEvent.builder().message("end").time(sw.elapsed(TimeUnit.SECONDS)).build()); + } + + log.info("call bot res:{} param:{}", resStr, param); + JsonObject resObj = GsonUtils.gson.fromJson(resStr, JsonObject.class); + + //处理结果中的错误 + handleResponse(resObj); + + String commond = JsonParser.parseString(resObj.get("data").getAsString()).getAsJsonObject().get("result").getAsJsonObject().get("data").getAsString(); + return commond; + } + + private static void handleResponse(JsonObject resObj) { + if (resObj.get("code").getAsInt() != 0) { + NotificationCenter.notice(resObj.get("message").getAsString(), NotificationType.ERROR); + throw new RuntimeException("callHttpServer error:" + resObj); + } + } + + // 在给定的JsonObject中添加version参数(class) + private static void addVersionParam(JsonObject resObj) { + Version version = new Version(); + resObj.addProperty(Const.CLIENT_VERSION, version.getVersion()); + resObj.addProperty(Const.CLIENT_NAME, version.getName()); + } + + private static void setModel(GenerateCodeReq req, JsonObject jsonReq) { + Action action = ActionUtils.getActionByReq(req); + String model = action == Action.CHAT ? AthenaContext.ins().getGptModel() : AthenaContext.ins().getNoChatModel(); + if (!Const.USE_BOT_MODEL.equals(model)) { + jsonReq.addProperty(Const.AI_MODEL_PARAM_KEY, model); + } + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ClassFinder.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ClassFinder.java similarity index 81% rename from athena-all/src/main/java/run/mone/m78/ip/service/ClassFinder.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ClassFinder.java index a4eec91e5..0b775226d 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/ClassFinder.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ClassFinder.java @@ -1,8 +1,8 @@ -package run.mone.m78.ip.service; +package com.xiaomi.youpin.tesla.ip.service; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.bo.ClassInfo; -import run.mone.m78.ip.util.AnnoUtils; +import com.xiaomi.youpin.tesla.ip.bo.ClassInfo; +import com.xiaomi.youpin.tesla.ip.util.AnnoUtils; import org.apache.commons.compress.utils.Lists; import java.util.List; diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ClipboardService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ClipboardService.java similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/service/ClipboardService.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ClipboardService.java index a6f52344c..b2b7f6d94 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/ClipboardService.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ClipboardService.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.service; +package com.xiaomi.youpin.tesla.ip.service; import lombok.SneakyThrows; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/CodeService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/CodeService.java new file mode 100644 index 000000000..43d5f35b9 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/CodeService.java @@ -0,0 +1,1774 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.intellij.codeInsight.lookup.LookupEx; +import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.ide.util.DirectoryUtil; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.searches.AllClassesSearch; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.Query; +import com.xiaomi.youpin.tesla.ip.bo.*; +import com.xiaomi.youpin.tesla.ip.common.*; +import com.xiaomi.youpin.tesla.ip.util.*; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import okhttp3.Response; +import org.apache.commons.compress.utils.Lists; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.MutableObject; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import run.mone.openai.OpenaiCall; +import run.mone.openai.ReqConfig; +import run.mone.openai.StreamListener; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.bo.AthenaClassInfo; +import run.mone.ultraman.common.ImportCode; +import run.mone.ultraman.common.TemplateUtils; +import run.mone.ultraman.service.AthenaCodeService; +import run.mone.ultraman.visitor.M78Visitor; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.function.BiConsumer; +import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + */ +@Slf4j +public class CodeService extends AbstractService { + + private static Gson gson = new Gson(); + + /** + * 打个某个指定的class + * + * @param project + * @param className + */ + public static PsiClass openJavaClass(Project project, String className) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> { + if (project == null) { + return null; + } + //Search for Java classes + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); + PsiClass psiClass = javaPsiFacade.findClass(className, GlobalSearchScope.allScope(project)); + + if (psiClass == null) { + return null; + } + // 创建 OpenFileDescriptor + OpenFileDescriptor openFileDescriptor = new OpenFileDescriptor(project, psiClass.getContainingFile().getVirtualFile()); + // 使用 FileEditorManager 打开 Java 类 + FileEditorManager.getInstance(project).openTextEditor(openFileDescriptor, true); + return psiClass; + }); + } + + + public static PsiClass[] getClassesInPackage(Project project, String packageName) { + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); + PsiPackage psiPackage = javaPsiFacade.findPackage(packageName); + if (psiPackage != null) { + PsiClass[] psiClasses = psiPackage.getClasses(); + return psiClasses; + } + return new PsiClass[0]; + } + + + /** + * 移动到方法的开头,且插入空行 + * Navigate to the beginning of the method and insert a blank line. + * + * @param project + */ + public static void moveToMethodAndInsertLine(Project project) { + PsiMethod method = getMethod(project); + if (null == method) { + return; + } + int offset = method.getTextRange().getStartOffset(); + Editor editor = getEditor(project); + CaretModel caretModel = editor.getCaretModel(); + caretModel.moveToOffset(offset); + WriteCommandAction.runWriteCommandAction(project, () -> editor.getDocument().insertString(offset, "\n\t")); + } + + //获取Editor中上一行的内容,如果是注释则返回注释内容,且当前所处位置是PsiClass中(class) + public static String getPreviousLineIfComment(Editor editor) { + Document document = editor.getDocument(); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + int lineNumber = document.getLineNumber(offset); + System.out.println(lineNumber); + if (lineNumber > 0) { + int previousLineStartOffset = document.getLineStartOffset(lineNumber - 1); + int previousLineEndOffset = document.getLineEndOffset(lineNumber - 1); + String previousLineText = document.getText(new TextRange(previousLineStartOffset, previousLineEndOffset)); + if (readCodeContinue(previousLineText)) { + return previousLineText; + } + } + return null; + } + + + //根据class name获取PsiClass(class) + public static PsiClass getPsiClassByName(Project project, String className) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> { + if (project == null || className == null || className.isEmpty()) { + return null; + } + JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); + return javaPsiFacade.findClass(className, GlobalSearchScope.allScope(project)); + }); + } + + + //给你class名字和method名字帮我获取这个PsiMethod(class) + public static String getPsiMethodByName(Project project, String className, String methodName) { + PsiClass psiClass = getPsiClassByName(project, className); + if (psiClass == null || methodName == null || methodName.isEmpty()) { + return null; + } + for (PsiMethod method : psiClass.getMethods()) { + if (methodName.equals(method.getName())) { + return getMethodAndLineNumbers(method); + } + } + return null; + } + + //我在Editor中选中一个被调用的方法(类似:),帮我找到这个方法的代码,并返回(class) + public static PsiMethod findSelectedMethod(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (editor == null) { + return null; + } + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (psiFile == null) { + return null; + } + PsiElement element = psiFile.findElementAt(editor.getCaretModel().getOffset()); + PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class); + return method; + } + + public static PsiMethod getPsiMethod(Project project, String className, String methodName) { + PsiClass psiClass = getPsiClassByName(project, className); + if (psiClass == null || methodName == null || methodName.isEmpty()) { + return null; + } + for (PsiMethod method : psiClass.getMethods()) { + if (methodName.equals(method.getName())) { + return method; + } + } + return null; + } + + /** + * 获取方法及行号相关信息 + */ + public static String getMethodAndLineNumbers(PsiMethod method) { + StringBuilder sb = new StringBuilder(); + PsiFile psiFile = method.getContainingFile(); + if (psiFile != null) { + Document document = PsiDocumentManager.getInstance(psiFile.getProject()).getDocument(psiFile); + if (document != null) { + TextRange methodRange = method.getTextRange(); + int startLine = document.getLineNumber(methodRange.getStartOffset()); + int endLine = document.getLineNumber(methodRange.getEndOffset()); + + for (int line = startLine; line <= endLine; line++) { + int lineStartOffset = document.getLineStartOffset(line); + int lineEndOffset = document.getLineEndOffset(line); + String lineText = document.getText(new TextRange(lineStartOffset, lineEndOffset)); + // 注释内容直接跳过 + if (readCodeContinue(lineText)) { + continue; + } + sb.append("line:" + (line + 1) + " code:" + lineText + "\n"); + } + } + } + return sb.toString(); + } + + public static String getClassName(PsiClass psiClass) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> psiClass.getQualifiedName()); + } + + private static boolean readCodeContinue(String lineCode) { + return lineCode.trim().startsWith("//") || lineCode.trim().startsWith("/*") + || lineCode.trim().startsWith("*") || lineCode.trim().startsWith("*/"); + } + + public static String getClassAndLineNumbers(PsiClass psiClass) { + StringBuilder sb = new StringBuilder(); + PsiFile psiFile = psiClass.getContainingFile(); + if (psiFile != null) { + Document document = PsiDocumentManager.getInstance(psiFile.getProject()).getDocument(psiFile); + if (document != null) { + TextRange methodRange = psiClass.getTextRange(); + int startLine = document.getLineNumber(methodRange.getStartOffset()); + int endLine = document.getLineNumber(methodRange.getEndOffset()); + + for (int line = startLine; line <= endLine; line++) { + int lineStartOffset = document.getLineStartOffset(line); + int lineEndOffset = document.getLineEndOffset(line); + String lineText = document.getText(new TextRange(lineStartOffset, lineEndOffset)); + sb.append("line:" + (line + 1) + " code:" + lineText + "\n"); + } + } + } + return sb.toString(); + } + + public static void addField(Project project, Document document, PsiClass psiClass, String code, String name) { + boolean find = Arrays.stream(psiClass.getFields()).filter(it -> it.getType().getCanonicalText().equals(name)).findAny().isPresent(); + if (!find) { + PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); + PsiField field = factory.createFieldFromText(code, null); + WriteCommandAction.runWriteCommandAction(project, () -> { + psiClass.add(field); + psiClass.getContainingFile().getVirtualFile().refresh(false, false); + PsiDocumentManager.getInstance(project).commitDocument(document); + }); + } + } + + /** + * 添加方法 + * + * @param project + * @param code + */ + public static void addMethod(Project project, String code) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); + PsiMethod method = factory.createMethodFromText(code, null); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiClass psiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); + WriteCommandAction.runWriteCommandAction(project, () -> { + psiClass.add(method); + psiClass.getContainingFile().getVirtualFile().refresh(false, false); + }); + } + + + /** + * 在光标处插入指定数量的空白行。 + * + * @param project 当前操作的项目对象 + * @param editor 当前操作的编辑器对象 + * @param numberOfBlankLines 要插入的空白行数 + */ + public static void insertBlankLinesAtCaret(Project project, Editor editor, int numberOfBlankLines) { + // 获取当前文档和光标所在的偏移量 + Document document = editor.getDocument(); + int caretOffset = editor.getCaretModel().getOffset(); + + // 创建一个包含指定数量空行的字符串 + StringBuilder newLines = new StringBuilder(); + for (int i = 0; i < numberOfBlankLines; i++) { + newLines.append("\n"); + } + + //保证线程安全 + ApplicationManager.getApplication().invokeLater(() -> { + WriteCommandAction.runWriteCommandAction(project, () -> { + // 在光标位置插入空行 + document.insertString(caretOffset, newLines.toString()); + + // 提交文档更改 + PsiDocumentManager.getInstance(project).commitDocument(document); + }); + }); + } + + + public static void insertCode(Project project, String code) { + insertCode(project, code, true); + } + + public static void insertCode(Project project, String code, boolean enter) { + Editor editor = getEditor(project); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + insertCode(project, code, enter, offset, editor); + } + + public static void insertCode(Project project, String code, boolean enter, int offset, Editor editor) { + log.info("insert code at offset:{}", offset); + WriteCommandAction.runWriteCommandAction(project, () -> { + Document document = editor.getDocument(); + document.insertString(offset, code + (enter ? "\n" : "")); + PsiDocumentManager.getInstance(project).commitDocument(document); + }); + formatCode(project); + } + + public static void insertCode(Project project, Document document, int offset, String code, boolean enter, boolean format) { + WriteCommandAction.runWriteCommandAction(project, () -> { + document.insertString(offset, code + (enter ? "\n" : "")); + PsiDocumentManager.getInstance(project).commitDocument(document); + }); + if (format) { + formatCode(project); + } + } + + /** + * 添加 import list + * + * @param project + * @param importStrList + */ + @SneakyThrows + public static void addImport(Project project, List importStrList) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + addImport(project, editor, importStrList); + } + + + public static void addImport(Project project, Editor editor, List importStrList) { + ImportUtils.addImport(project, editor, importStrList); + } + + + public static PsiClass createPsiClass(PsiElementFactory factory, String className) { + return ImportUtils.createPsiClass(factory, className); + } + + + /** + * 根据需求直接生成方法 + * + * @param project + * @param prompt + */ + public static void generateMethod(Project project, String prompt) { + } + + /** + * 向方法中添加语句 + * + * @param project + * @param code + */ + public static void addStatementToMethod(Project project, String code) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); + PsiStatement statement = factory.createStatementFromText(code, null); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiMethod psiMethod = PsiTreeUtil.getParentOfType(elementAtCaret, PsiMethod.class); + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiCodeBlock body = psiMethod.getBody(); + body.addBefore(statement, body.getFirstBodyElement()); + psiMethod.getContainingFile().getVirtualFile().refresh(false, false); + }); + } + + /** + * 把代码写入Idea Editor + * + * @param project + * @param editor + * @param code + */ + public static void writeCode2(Project project, Editor editor, String code) { + writeCode4(project, editor, code, true); + } + + public static void writeCode4(Project project, Editor editor, String code, boolean appendT) { + @NotNull Document document = editor.getDocument(); + CaretModel caretModel = editor.getCaretModel(); + WriteCommandAction.runWriteCommandAction(project, () -> { + int offset = caretModel.getOffset(); + Pair pair = lineAndColumnNum(document, offset); + int line = pair.getKey(); + for (; ; ) { + int startOffset = caretModel.getOffset(); + int endOffset = document.getLineEndOffset(line - 1); + String content = document.getText(new TextRange(startOffset, endOffset)); + //如果后边是空的,则直接添加 + if (StringUtils.isEmpty(content.trim())) { + String s = ""; + //补一个tab,看起来更美观 + if (isFirstColumn(startOffset, editor)) { + s = appendT ? "\t" + code : "" + code; + } else { + s = code; + } + document.insertString(startOffset, s); + caretModel.moveToOffset(startOffset + s.length()); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); + break; + } else { //否则插入空行 + editor.getCaretModel().moveToOffset(endOffset); + addLineBreak(project, document, line, 1); + PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); + } + } + }); + } + + /** + * 用于关闭完成操作 + * 获取项目对应的编辑器,如果不为空则隐藏该项目的活动查找 + */ + public static void closeCompletion(Project project) { + if (project == null || project.isDisposed()) { + return; + } + @Nullable LookupEx lookup = LookupManager.getInstance(project).getActiveLookup(); + if (null != lookup) { + LookupManager.getInstance(project).hideActiveLookup(); + } + } + + + /** + * 将编辑器中的光标移动到当前行的末尾。 + * + * @param editor 需要操作的编辑器对象 + */ + public static void moveCaretToEndOfLine(Editor editor) { + Document document = editor.getDocument(); + CaretModel caretModel = editor.getCaretModel(); + int lineNumber = document.getLineNumber(caretModel.getOffset()); + int lineEndOffset = document.getLineEndOffset(lineNumber); + caretModel.moveToOffset(lineEndOffset); + } + + //移动光标到指定PsiMethod上(method) + public static void moveCaretToMethod(Editor editor, PsiMethod method) { + int offset = method.getTextOffset(); + LogicalPosition logicalPosition = editor.offsetToLogicalPosition(offset); + editor.getCaretModel().moveToLogicalPosition(logicalPosition); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + + + //移动光标到指定PsiComment的最后位置(class) + public static void moveCaretToCommentEnd(Editor editor, PsiComment comment) { + int offset = comment.getTextRange().getEndOffset(); + LogicalPosition logicalPosition = editor.offsetToLogicalPosition(offset); + editor.getCaretModel().moveToLogicalPosition(logicalPosition); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + + public static void moveCaretToOffset(Editor editor, int offset) { + LogicalPosition logicalPosition = editor.offsetToLogicalPosition(offset); + editor.getCaretModel().moveToLogicalPosition(logicalPosition); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + } + + + // 判断光标Caret所在位置后面是否没有任何字符 + public static boolean isCaretAtEndOfLine(Editor editor) { + Document document = editor.getDocument(); + CaretModel caretModel = editor.getCaretModel(); + int caretOffset = caretModel.getOffset(); + int lineNumber = document.getLineNumber(caretOffset); + int lineEndOffset = document.getLineEndOffset(lineNumber); + return caretOffset >= lineEndOffset; + } + + // 判断光标向前遇到的第一个字符是不是 "{", "}" , ";" + public static boolean isPreCharBrace(Editor editor) { + if (editor == null) { + return false; + } + Document document = editor.getDocument(); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + if (offset == 0) { + return false; + } + CharSequence text = document.getCharsSequence(); + for (int i = offset - 1; i >= 0; i--) { + char currentChar = text.charAt(i); + if (Character.isWhitespace(currentChar)) { + continue; + } + return currentChar == '{' || currentChar == '}' || currentChar == ';'; + } + return false; + } + + + /** + * 将编辑器的光标移动到方法的结束位置。 + * + * @param editor 编辑器对象 + * @param method 要移动光标到其结束位置的方法对象 + */ + public static void moveCaretToMethodEnd(Editor editor, PsiMethod method) { + if (method == null || null == method.getBody()) { + return; + } + PsiJavaToken rBrace = method.getBody().getRBrace(); + if (Objects.isNull(rBrace)) { + return; + } + int methodEndOffset = rBrace.getTextOffset(); + editor.getCaretModel().moveToOffset(methodEndOffset - 1); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + } + + + private static boolean isFirstColumn(int offset, Editor editor) { + int lineNumber = editor.getDocument().getLineNumber(offset); + int lineStartOffset = editor.getDocument().getLineStartOffset(lineNumber); + boolean isFirstColumn = (offset - lineStartOffset) == 0; + return isFirstColumn; + } + + + public static void writeCode3(Project project, String code) { + UltramanConsole.append(project, code, false); + } + + + public static Pair lineAndColumnNum(Document document, int offset) { + int lineNumber = document.getLineNumber(offset) + 1; + int columnNumber = offset - document.getLineStartOffset(lineNumber - 1); + return Pair.of(lineNumber, columnNumber); + } + + + /** + * 移动到指定行号 + * + * @param project + * @param lineNumber + */ + public static void moveLine(Project project, int lineNumber) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + LogicalPosition position = new LogicalPosition(lineNumber - 1, 0); // 创建逻辑位置对象 + editor.getCaretModel().moveToLogicalPosition(position); // 将光标移动到指定行 + } + + + /** + * 关闭当前Editor + * + * @param project + */ + public static void closeEditor(Project project) { + EditorUtils.closeEditor(project); + } + + /** + * 格式化当前代码 + */ + public static void formatCode(Project project) { + if (null == project) { + return; + } + WriteCommandAction.runWriteCommandAction(project, () -> { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project); + codeStyleManager.reformat(psiFile); + }); + } + + @Nullable + public static Project deleteCode(@NotNull Editor editor) { + Project project = editor.getProject(); + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiMethod psiMethod = CodeService.getMethod(project); + if (null != psiMethod) { + String methodText = psiMethod.getText(); + methodText = methodText.replace("//❁", ""); + PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); + PsiMethod newMethod = factory.createMethodFromText(methodText, psiMethod); + psiMethod.replace(newMethod); + } + if (project != null && editor.getDocument() != null) { + PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); + } + }); + return project; + } + + + /** + * 替换指定PsiFile文件的内容为新的文本内容 + * + * @param psiFile 要替换内容的PsiFile对象 + * @param newContent 新的文件内容字符串 + */ + public static void replaceFileContent(PsiFile psiFile, String newContent) { + Project project = psiFile.getProject(); + PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); + Document document = psiDocumentManager.getDocument(psiFile); + + if (document != null) { + // 开始一个写操作,以修改文件内容 + WriteCommandAction.runWriteCommandAction(project, () -> { + document.setText(newContent); + psiDocumentManager.commitDocument(document); + }); + } + } + + + /** + * 删除指定行 + * + * @param project + * @param lineToDelete + */ + public static void deleteLine(Project project, int lineToDelete) { + lineToDelete = lineToDelete - 1; + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + Document document = editor.getDocument(); + int startOffset = document.getLineStartOffset(lineToDelete); + int endOffset = document.getLineEndOffset(lineToDelete); + WriteCommandAction.runWriteCommandAction(project, () -> { + document.deleteString(startOffset, endOffset); + }); + + ApplicationManager.getApplication().invokeLater(() -> editor.getContentComponent().repaint()); + } + + + /** + * 返回所有method + * + * @param project + * @return + */ + public static List methods(Project project) { + Editor editor = getEditor(project); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(editor.getCaretModel().getOffset()); + PsiClass currentPsiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); + return Arrays.stream(currentPsiClass.getAllMethods()).map(it -> it.getName()).collect(Collectors.toList()); + } + + + /** + * 通过module查询会快点 + * + * @param project + * @param module + * @param name + * @return + */ + public static PsiClass getPsiClass(Project project, Module module, String name) { + PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(name, GlobalSearchScope.moduleScope(module)); + return psiClass; + } + + + public static List methods(PsiClass psiClass) { + return Arrays.stream(psiClass.getMethods()).filter(it -> it.getModifierList().hasModifierProperty("public")).map(it -> it.getName()).collect(Collectors.toList()); + } + + + public static List fields(Project project) { + Editor editor = getEditor(project); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(editor.getCaretModel().getOffset()); + PsiClass currentPsiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); + return Arrays.stream(currentPsiClass.getAllFields()).map(it -> it.getName()).collect(Collectors.toList()); + } + + public static PsiMethod getMethod(Project project) { + Editor editor = getEditor(project); + if (null == editor) { + return null; + } + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + //如果有选中内容,则分析选中的是否是PsiMethod + if (isTextSelected(editor)) { + PsiElement pe = getSelectedPsiMethod(editor, psiFile); + if (pe instanceof PsiMethod) { + return (PsiMethod) pe; + } + } + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiMethod method = PsiTreeUtil.getParentOfType(elementAtCaret, PsiMethod.class); + return method; + } + + public static String getMethodCode(Project project) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> getMethod(project).getText()); + } + + public static PsiField getPsiField(Project project) { + Editor editor = getEditor(project); + if (null == editor) { + return null; + } + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiField psiField = PsiTreeUtil.getParentOfType(elementAtCaret, PsiField.class); + return psiField; + } + + + public static boolean isTextSelected(Editor editor) { + return editor.getSelectionModel().hasSelection(); + } + + public static String getSelectedText(Editor editor) { + if (isTextSelected(editor)) { + SelectionModel selectionModel = editor.getSelectionModel(); + String selectedText = selectionModel.getSelectedText(); + return selectedText; + } + return ""; + } + + + public static PsiElement getSelectedPsiMethod(Editor editor, PsiFile psiFile) { + SelectionModel selectionModel = editor.getSelectionModel(); + int start = selectionModel.getSelectionStart(); + int end = selectionModel.getSelectionEnd(); + for (int i = start; i < end; i++) { + PsiElement element = psiFile.findElementAt(i); + @Nullable PsiMethod pm = PsiTreeUtil.getParentOfType(element, PsiMethod.class); + if (null != pm) { + return pm; + } + } + return null; + } + + public static PsiMethod getPsiMethodWithLineNum(Project project, Document document, int lineNum) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> { + @Nullable PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + int start = document.getLineStartOffset(lineNum - 1); + int end = document.getLineEndOffset(lineNum - 1); + for (int i = start; i < end; i++) { + PsiElement element = psiFile.findElementAt(i); + @Nullable PsiMethod pm = PsiTreeUtil.getParentOfType(element, PsiMethod.class); + if (null != pm) { + return pm; + } + } + return null; + }); + } + + public static PsiField getPsiFieldWithLineNum(Project project, Document document, int lineNum) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> { + @Nullable PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + int start = document.getLineStartOffset(lineNum - 1); + int end = document.getLineEndOffset(lineNum - 1); + for (int i = start; i < end; i++) { + PsiElement element = psiFile.findElementAt(i); + @Nullable PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class); + if (null != field) { + return field; + } + } + return null; + }); + } + + + public static PsiClass getPsiClassWithLineNum(Project project, Document document, int lineNum) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> { + @Nullable PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + int start = document.getLineStartOffset(lineNum - 1); + int end = document.getLineEndOffset(lineNum - 1); + for (int i = start; i < end; i++) { + PsiElement element = psiFile.findElementAt(i); + @Nullable PsiClass pm = PsiTreeUtil.getParentOfType(element, PsiClass.class); + if (null != pm) { + return pm; + } + } + return null; + }); + + } + + + public static TextRange getTextRange(Project project, final Class clazz) { + Editor editor = getEditor(project); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + + while (true) { + if (elementAtCaret.getClass().equals(clazz)) { + return elementAtCaret.getTextRange(); + } + elementAtCaret = elementAtCaret.getParent(); + if (null == elementAtCaret) { + return null; + } + } + } + + public static String getText(Project project, Class clazz) { + Editor editor = getEditor(project); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiElement element = PsiTreeUtil.getParentOfType(elementAtCaret, clazz); + return element.getText(); + } + + public static TextRange getParentTextRange(Project project) { + Editor editor = getEditor(project); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + return psiFile.findElementAt(offset).getParent().getParent().getTextRange(); + } + + + public static PsiClass getPsiClass(Project project) { + Editor editor = getEditor(project); + if (null == editor) { + return null; + } + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (psiFile != null) { + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiClass psiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); + return psiClass; + } else { + return null; + } + } + + public static PsiClass getPsiClassInRead(Project project) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> { + return getPsiClass(project); + }); + } + + public static PsiElement getParentOfType(Project project, Class clazz) { + Editor editor = getEditor(project); + if (null == editor) { + return null; + } + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiElement res = PsiTreeUtil.getParentOfType(elementAtCaret, clazz); + return res; + } + + + public static PsiClass getPsiClass2(Project project) { + Editor editor = getEditor(project); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiClass psiClass = Arrays.stream(psiFile.getChildren()).filter(it -> it instanceof PsiClass).map(it -> (PsiClass) it).findFirst().get(); + return psiClass; + } + + public static PsiFile getPsiFile(Project project) { + Editor editor = getEditor(project); + return PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + } + + + public static PsiMethod getMethod(PsiClass psiClass, String methodName) { + PsiMethod[] methods = psiClass.findMethodsByName(methodName, false); + return methods[0]; + } + + + public static Map getLineContentsAndNumbersForMethod(PsiMethod method) { + Map lineContentsAndNumbers = new HashMap<>(); + PsiCodeBlock codeBlock = method.getBody(); + if (codeBlock != null) { + PsiFile containingFile = codeBlock.getContainingFile(); + Document document = PsiDocumentManager.getInstance(method.getProject()).getDocument(containingFile); + for (PsiElement element : codeBlock.getChildren()) { + int startOffset = element.getTextOffset(); + int endOffset = startOffset + element.getTextLength(); + int startLineNumber = document.getLineNumber(startOffset); + int endLineNumber = document.getLineNumber(endOffset); + for (int i = startLineNumber; i <= endLineNumber; i++) { + int lineStartOffset = document.getLineStartOffset(i); + int lineEndOffset = document.getLineEndOffset(i); + TextRange textRange = new TextRange(lineStartOffset, lineEndOffset); + String lineContent = document.getText(textRange).trim(); + lineContentsAndNumbers.put(i + 1, lineContent); + } + } + } + return lineContentsAndNumbers; + } + + + public static int getMethodLineCount(PsiMethod method) { + if (method == null) { + return 0; + } + PsiCodeBlock body = method.getBody(); + if (body == null) { + return 0; + } + Document document = getEditor(method.getProject()).getDocument(); + if (document == null) { + return 0; + } + int startLine = document.getLineNumber(body.getTextRange().getStartOffset()); + int endLine = document.getLineNumber(body.getTextRange().getEndOffset()); + return endLine - startLine + 1; + } + + public static String getClassText(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + return editor.getDocument().getText(); + } + + public static String getClassText2(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + Document document = editor.getDocument(); + int offset = editor.getCaretModel().getOffset(); + String text = document.getText(); + return text.substring(0, offset) + "//❁" + text.substring(offset); + } + + + /** + * 根据prompt删除注解 + * + * @param project + */ + public static void removeComments(Project project) { + } + + + public static void createEmptyClass(Project project, String moduleName, String packageName, String className) { + createEmptyClass(project, moduleName, packageName, className, false); + } + + /** + * 创建空的类 + * + * @param project + * @param packageName + * @param className + */ + public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath) { + PsiClassUtils.createEmptyClass(project, moduleName, packageName, className, testPath); + } + + + public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath, boolean isInterface) { + PsiClassUtils.createEmptyClass(project, moduleName, packageName, className, testPath, false, null, isInterface); + } + + + public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath, List annoList) { + PsiClassUtils.createEmptyClass(project, moduleName, packageName, className, testPath, annoList); + } + + + public static PsiDirectory getSourceDirectory(Project project, String moduleName, boolean testPath) { + return PsiClassUtils.getSourceDirectory(project, moduleName, testPath); + } + + public static PsiDirectory getSourceDirectory(Project project, boolean testPath, String packagePath) { + return PsiClassUtils.getSourceDirectory(project, testPath, packagePath); + } + + public static PsiDirectory getSourceDirectory(Project project) { + return PsiClassUtils.getSourceDirectory(project, "", false); + } + + + public static List getClassByServiceAnno(Project project, String anno) { + List className = Lists.newArrayList(); + PsiDirectory psiDirectory = getSourceDirectory(project); + List allJavaFiles = getAllJavaFiles(psiDirectory); + for (PsiJavaFile javaFile : allJavaFiles) { + for (PsiClass psiClass : javaFile.getClasses()) { + PsiAnnotation annotation = psiClass.getAnnotation(anno); + if (null != annotation) { + className.add(psiClass.getName()); + } + } + } + return className; + } + + private static List getAllJavaFiles(PsiDirectory dir) { + List javaFiles = new ArrayList<>(); + for (PsiFile file : dir.getFiles()) { + if (file instanceof PsiJavaFile) { + javaFiles.add((PsiJavaFile) file); + } + } + for (PsiDirectory subdir : dir.getSubdirectories()) { + javaFiles.addAll(getAllJavaFiles(subdir)); + } + return javaFiles; + } + + + /** + * 创建包路径 + * + * @param project + * @param packageName + */ + public static void createPackage(Project project, String packageName) { + if (project != null) { + // 获取项目的根目录 + PsiDirectory rootDirectory = PsiManager.getInstance(project).findDirectory(project.getBaseDir()); + if (rootDirectory != null) { + // 创建新的包 + @NonNls @NotNull String path = ProjectRootManager.getInstance(project).getContentSourceRoots()[0].getPath(); + WriteCommandAction.runWriteCommandAction(project, () -> { + DirectoryUtil.mkdirs(rootDirectory.getManager(), path + "/" + packageName.replace('.', '/')); + }); + } + } + } + + public static void createPackageInModule(Module module, String packageName) { + // 获取模块的根模型 + ModifiableRootModel modifiableRootModel = ModuleRootManager.getInstance(module).getModifiableModel(); + try { + // 获取模块的内容入口 + ContentEntry[] contentEntries = modifiableRootModel.getContentEntries(); + if (contentEntries.length > 0) { + // 通常情况下,我们使用第一个内容入口 + ContentEntry contentEntry = contentEntries[0]; + // 获取源文件夹的目录 + PsiDirectory directory = PsiManager.getInstance(module.getProject()).findDirectory(contentEntry.getFile()); + if (directory != null) { + // 使用 JavaDirectoryService 来创建或获取包 + PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(directory); + if (psiPackage != null) { + // 创建包路径 + String[] names = packageName.split("\\."); + for (String name : names) { + PsiDirectory subdirectory = directory.findSubdirectory(name); + if (subdirectory == null) { + // 如果子目录不存在,则创建它 + directory = directory.createSubdirectory(name); + } else { + directory = subdirectory; + } + } + } + } + } + } finally { + // 提交模块的根模型更改 + modifiableRootModel.commit(); + } + } + + public static List listMethodInfo(String clazz) { + return Lists.newArrayList(); + } + + /** + * 生成一个moon demo的handler + * + * @param project + */ + public static void generateMoonHandler(Project project) { + // 获取项目的根目录 + PsiDirectory rootDirectory = PsiManager.getInstance(project).findDirectory(project.getBaseDir()); + if (null != rootDirectory) { + @NonNls @NotNull String path = ProjectRootManager.getInstance(project).getContentSourceRoots()[0].getPath(); + } + String handlerName = "MoonDemoHandler"; + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(editor.getCaretModel().getOffset()); + // 获取最近的PsiClass + PsiClass currentPsiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); + PsiJavaFile psiJavaFile = (PsiJavaFile) currentPsiClass.getContainingFile(); + PsiPackage psiPackage = JavaPsiFacade.getInstance(currentPsiClass.getProject()).findPackage(psiJavaFile.getPackageName()); + String packageStr = psiPackage.getQualifiedName(); + // 创建一个类,写入class描述符是为了能打开它 + String text = "public class " + handlerName + "{}"; + JavaClassUtils.createClass(project, editor, handlerName, text, false, packageStr); + String qualifiedName = currentPsiClass.getQualifiedName(); + String packageName = qualifiedName.substring(0, qualifiedName.lastIndexOf('.')); + deleteCode(project); + generateCodeWithAi(project, Prompt.get("moon_handler"), new String[]{packageName, "MoonDemoHandler"}); + } + + /** + * 获取当前类的package 路径 + * + * @param project + * @return 包路径 + */ + public static String getPackagePath(Project project) { + Editor editor = getEditor(project); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(editor.getCaretModel().getOffset()); + // 获取最近的PsiClass + PsiClass currentPsiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); + PsiJavaFile psiJavaFile = (PsiJavaFile) currentPsiClass.getContainingFile(); + PsiPackage psiPackage = JavaPsiFacade.getInstance(currentPsiClass.getProject()).findPackage(psiJavaFile.getPackageName()); + return psiPackage.getQualifiedName(); + } + + + @Override + public void execute(Context context, AnActionEvent e) { + this.next(context, e); + } + + public static void addClassAnno(Project project, PsiClass psiClass, List annoList) { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); + PsiModifierList modifierList = psiClass.getModifierList(); + PsiAnnotation[] annotations = modifierList.getAnnotations(); + // 原来的注解 + List oldAnnoList = Arrays.stream(annotations).map(oldAnno -> "@" + oldAnno.getQualifiedName().substring(oldAnno.getQualifiedName().lastIndexOf('.') + 1)).toList(); + List addAnno = annoList.stream().filter(anno -> !oldAnnoList.contains(anno)).toList(); + List psiAnnotationList = addAnno.stream().map(i -> elementFactory.createAnnotationFromText(i, null)).toList(); + WriteCommandAction.runWriteCommandAction(project, () -> { + psiAnnotationList.forEach(anno -> modifierList.addBefore(anno, modifierList.getFirstChild())); + }); + } + + /** + * 删除这个编辑器中的所有内容 + * + * @param project + */ + public static void deleteCode(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + WriteCommandAction.runWriteCommandAction(project, () -> { + editor.getDocument().setText(""); + }); + Caret caret = editor.getCaretModel().getPrimaryCaret(); + caret.moveToOffset(0); + } + + public static void deleteTextRange(Project project, TextRange range) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + WriteCommandAction.runWriteCommandAction(project, () -> { + Document document = editor.getDocument(); + document.deleteString(range.getStartOffset(), range.getEndOffset()); + PsiDocumentManager.getInstance(project).commitDocument(document); + }); + } + + + public static boolean isClass(String text) { + if (text.contains(" class ")) { + return true; + } + return false; + } + + public static boolean isPrivateField(String text) { + if (text.contains("private") && text.contains(";")) { + return true; + } + return false; + } + + + private static Integer getNumFromStr(String str) { + Pattern pattern = Pattern.compile("\\d+"); + Matcher matcher = pattern.matcher(str); + String lineNumber = "0"; + if (matcher.find()) { + lineNumber = matcher.group(); + } + return Integer.valueOf(lineNumber); + } + + /** + * 通过chatgpt生成代码,然后插入编辑器中 + * + * @param project + * @param context + * @param prompt + */ + public static void generateCodeWithAi(Project project, String context, String[] prompt, BiConsumer consumer) { + String key = ConfigUtils.getConfig().getChatgptKey(); + try { + OpenaiCall.callStream(key, ProxyUtils.getProxy(), context, prompt, new StreamListener() { + @Override + public void onEvent(String str) { + consumer.accept(project, str); + } + + @Override + public void end() { + formatCode(project); + } + }, ReqConfig.builder().maxTokens(2000).build()); + } catch (Throwable ex) { + ex.printStackTrace(); + } + } + + public static void generateCodeWithAi2(Project project, String promptName, String[] pramas, BiConsumer consumer) { + generateCodeWithAi3(project, promptName, pramas, Maps.newHashMap(), consumer); + } + + + public static void generateCodeWithAi3(Project project, String promptName, String[] pramas, Map paramMap, BiConsumer consumer) { + generateCodeWithAi4(project, promptName, pramas, paramMap, consumer, new MessageConsumer()); + } + + + public static void generateCodeWithAi4(Project project, String promptName, String[] pramas, Map paramMap, BiConsumer consumer, MessageConsumer messageConsumer) { + generateCodeWithAi5(GenerateCodeReq.builder().promptName(promptName).project(project).build(), project, promptName, pramas, paramMap, consumer, messageConsumer); + } + + + @SneakyThrows + public static String call(String promptName, Map paramMap) { + //开启了本地模式(而且只有admin权限的用户可以) + if (ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_LOCAL, "false").equals("true")) { + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + String prompt = promptInfo.getData(); + if (StringUtils.isNotEmpty(prompt)) { + prompt = TemplateUtils.renderTemplate(prompt, paramMap.entrySet().stream().collect(Collectors.toMap(k -> k.getKey(), v -> v.getValue().toString()))); + log.info(prompt); + } + } + + + ProxyAsk pa = new ProxyAsk(); + if (StringUtils.isNotEmpty(AthenaContext.ins().getGptModel())) { + pa.setModel(AthenaContext.ins().getGptModel()); + } + String id = UUID.randomUUID().toString(); + pa.setId(id); + pa.setPromptName(promptName); + pa.setParams(new String[]{}); + pa.setParamMap(paramMap); + pa.setZzToken(ConfigUtils.getConfig().getzToken()); + NotificationCenter.notice(null, "call prompt:" + promptName + " model:" + pa.getModel(), true); + StringBuilder sb = new StringBuilder(); + CountDownLatch latch = new CountDownLatch(1); + long begin = System.currentTimeMillis(); + OpenaiCall.callStream2(gson.toJson(pa), new StreamListener() { + @Override + public void begin() { + } + + @Override + public void onEvent(String str) { + str = new String(Base64.getDecoder().decode(str.getBytes(Charset.forName("utf8"))), Charset.forName("utf8")); + log.info(str + " " + Arrays.toString(str.getBytes(Charset.forName("utf8")))); + sb.append(str); + } + + @Override + public void onFailure(Throwable t, Response response) { + if (null != t) { + log.error(t.getMessage(), t); + } + String message = getErrorMessage(t, response); + sb.append(message); + latch.countDown(); + } + + @Override + public void end() { + latch.countDown(); + } + }, ReqConfig.builder().connectTimeout(TimeUnit.SECONDS.toMillis(10)).readTimeout(TimeUnit.SECONDS.toMillis(20)).maxTokens(4096).askUrl(ConfigUtils.getConfig().getAiProxy() + "/ask").build()); + latch.await(10, TimeUnit.SECONDS); + NotificationCenter.notice(null, "call prompt:" + promptName + " model:" + pa.getModel() + "use time:" + (System.currentTimeMillis() - begin) + "ms", true); + return sb.toString(); + } + + + public static boolean isCursorInComment(Editor editor) { + // 获取光标的逻辑位置 + LogicalPosition logicalPosition = editor.getCaretModel().getLogicalPosition(); + int offset = editor.logicalPositionToOffset(logicalPosition); + + // 获取当前文件 + Document document = editor.getDocument(); + + // 获取光标位置 + CaretModel caretModel = editor.getCaretModel(); + int lineNumber = logicalPosition.line; + + // 获取当前行的文本 + String lineText = document.getText(new TextRange(document.getLineStartOffset(lineNumber), document.getLineEndOffset(lineNumber))).trim(); + + // 检查该行是否以 "//" 开始 + if (lineText.startsWith("//")) { + return true; + } + + // 检查光标是否在多行注释中 + if (editor.getProject() != null) { + PsiFile psiFile = PsiDocumentManager.getInstance(editor.getProject()).getPsiFile(document); + if (psiFile == null) { + return false; + } + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiComment comment = PsiTreeUtil.getParentOfType(elementAtCaret, PsiComment.class); + return elementAtCaret instanceof PsiComment || comment != null; + } else { + return false; + } + } + + public static boolean isAtMultiCommentEnd(String line) { + return StringUtils.isNotEmpty(line) && line.trim().equals("*/"); + } + + public static boolean hasValidCharCnt(String line) { + return line.trim().length() > 2; + } + + // 当前caret是否不在任何方法里但是在类的大括号范围内, 且不在类的第一行(包含"{"的行)和最后一行(包含"}"的行) + public static boolean isCaretInClassButNotInMethod(Editor editor) { + Document document = editor.getDocument(); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + int lineNumber = document.getLineNumber(offset); + + PsiFile psiFile = PsiDocumentManager.getInstance(editor.getProject()).getPsiFile(document); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiClass psiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); + PsiMethod psiMethod = PsiTreeUtil.getParentOfType(elementAtCaret, PsiMethod.class); + + if (psiClass == null || psiMethod != null) { + return false; + } + + int classStartLine = document.getLineNumber(psiClass.getTextRange().getStartOffset()); + int classEndLine = document.getLineNumber(psiClass.getTextRange().getEndOffset()); + + return lineNumber > classStartLine && lineNumber < classEndLine; + } + + + // 当前caret所在行是否只有一个注解 + public static boolean isCaretLineOnlyAnnotation(Editor editor) { + Document document = editor.getDocument(); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + int lineNumber = document.getLineNumber(offset); + int lineStartOffset = document.getLineStartOffset(lineNumber); + int lineEndOffset = document.getLineEndOffset(lineNumber); + String lineText = document.getText(new TextRange(lineStartOffset, lineEndOffset)).trim(); + return lineText.startsWith("@") && !lineText.contains(" "); + } + + + public static void generateCodeWithAi5(GenerateCodeReq req, Project project, String promptName, String[] pramas, Map paramMap, BiConsumer consumer, MessageConsumer messageConsumer) { + try { + ProxyAsk pa = new ProxyAsk(); + setModelAndDebug(project, pa, paramMap, req); + String id = UUID.randomUUID().toString(); + pa.setId(id); + pa.setPromptName(promptName); + pa.setParams(pramas); + pa.setParamMap(paramMap); + pa.setZzToken(ConfigUtils.getConfig().getzToken()); + String projectName = project.getName(); + String strReq = gson.toJson(pa); + log.info("ask req:{}", strReq); + OpenaiCall.callStream2(strReq, new StreamListener() { + + @Override + public void begin() { + messageConsumer.begin(AiMessage.builder().projectName(projectName).type(AiMessageType.begin).id(id).build()); + } + + @Override + public void onEvent(String str) { + str = Base64Utils.decodeBase64String(str); + log.debug(str + " " + Arrays.toString(str.getBytes(Charset.forName("utf8")))); + consumer.accept(project, str); + messageConsumer.onEvent(AiMessage.builder().projectName(projectName).type(AiMessageType.process).id(id).text(str).build()); + } + + @Override + public void onFailure(Throwable t, Response response) { + if (null != t) { + log.error(t.getMessage(), t); + } + String message = getErrorMessage(t, response); + messageConsumer.failure(AiMessage.builder().projectName(projectName).id(id).text(message).type(AiMessageType.failure).build()); + NotificationCenter.notice("调用ai proxy发生了错误:" + message, NotificationType.ERROR); + } + + @Override + public void end() { + messageConsumer.end(AiMessage.builder().projectName(projectName).type(AiMessageType.success).id(id).build()); + if (req.isFormat()) { + formatCode(project); + } + } + }, ReqConfig.builder().connectTimeout(TimeUnit.SECONDS.toMillis(10)).readTimeout(TimeUnit.SECONDS.toMillis(60)).maxTokens(4000).askUrl(ConfigUtils.getConfig().getAiProxy() + "/ask").build()); + } catch (Throwable ex) { + log.error(ex.getMessage(), ex); + } + } + + public static void setModelAndDebug(Project project, ProxyAsk pa, Map paramMap, GenerateCodeReq req) { + int size = getCodeSize(paramMap); + if (StringUtils.isNotEmpty(AthenaContext.ins().getGptModel())) { + pa.setModel(AthenaContext.ins().getGptModel()); + int maxToken = AthenaContext.ins().getModel(pa.getModel()).getMaxToken(); + pa.setMaxToken(maxToken); + } else { + pa.setMaxToken(4000); + } + NotificationCenter.notice(project, "prompt:" + req.getPromptName() + " param size:" + size + " model:" + pa.getModel(), true); + pa.setDebug(AthenaContext.ins().isDebugAiProxy()); + } + + private static int getCodeSize(Map paramMap) { + int size = 0; + if (paramMap.containsKey("code")) { + size += paramMap.get("code").length(); + } + if (paramMap.containsKey("context")) { + size += paramMap.get("context").length(); + } + if (paramMap.containsKey("comment") && null != paramMap.get("comment")) { + size += paramMap.get("comment").length(); + } + return size; + } + + @NotNull + private static String getErrorMessage(Throwable t, Response response) { + String message = ""; + if (null != response) { + message = response.message(); + if (StringUtils.isNotEmpty(message)) { + message = "错误原因:" + message; + } else { + message = ""; + } + } + if (null != t) { + message += t.getMessage(); + } + return message; + } + + + public static void generateCodeWithAi(Project project, String context, String[] prompt) { + generateCodeWithAi(project, context, prompt, (p, code) -> { + writeCode(p, code); + }); + } + + /** + * 直接插入代码 + * + * @param project + * @param str + */ + public static void writeCode(Project project, String str) { + WriteCommandAction.runWriteCommandAction(project, () -> { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + Caret caret = editor.getCaretModel().getPrimaryCaret(); + Document document = editor.getDocument(); + int offset = caret.getOffset(); + editor.getDocument().insertString(offset, str); + int maxOffset = document.getTextLength(); + int nextLineStartOffset = caret.getOffset() + str.length(); + int insertOffset = maxOffset > nextLineStartOffset ? nextLineStartOffset : maxOffset; + caret.moveToOffset(insertOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); + } + ); + } + + /** + * 选中一个方法 + * + * @param project + */ + public static PsiMethod selectMethod(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (null == editor) { + return null; + } + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + if (psiFile == null) { + return null; + } + PsiElement element = psiFile.findElementAt(editor.getCaretModel().getOffset()); + PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class); + return method; + } + + public static void deleteMethod(Project project, PsiMethod method) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (null == editor) { + return; + } + + if (null == method) { + return; + } + Document document = editor.getDocument(); + int startOffset = method.getTextRange().getStartOffset(); + + editor.getCaretModel().getPrimaryCaret().moveToOffset(startOffset); + + int endOffset = method.getTextRange().getEndOffset(); + WriteCommandAction.runWriteCommandAction(project, () -> document.deleteString(startOffset, endOffset)); + } + + public static void deletePsiClass(Project project, PsiClass psiClass) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + Document document = editor.getDocument(); + int startOffset = psiClass.getTextRange().getStartOffset(); + editor.getCaretModel().getPrimaryCaret().moveToOffset(startOffset); + int endOffset = psiClass.getTextRange().getEndOffset(); + WriteCommandAction.runWriteCommandAction(project, () -> document.deleteString(startOffset, endOffset)); + } + + public static Editor getEditor(Project project) { + return EditorUtils.getEditor(project); + } + + public static Document getDocument(Project project) { + return getEditor(project).getDocument(); + } + + /** + * 添加空行 + * + * @param project + * @param document + * @param num + */ + public static void addLineBreak(Project project, Document document, int lineNum, int num) { + String v = "\n\t"; + int lineEndOffset = document.getLineEndOffset(lineNum - 1); + PsiClass pc = getPsiClass(project); + if (null != pc) { + int classOffset = pc.getTextRange().getEndOffset(); + lineEndOffset = Math.min(lineEndOffset, classOffset - 1); + v = "\n"; + } + int offset = lineEndOffset; + String str = Strings.repeat(v, num); + WriteCommandAction.runWriteCommandAction(project, () -> document.insertString(offset, str)); + PsiDocumentManager.getInstance(project).commitDocument(document); + } + + public static List getClassList(Project project, String end, String mn) { + GlobalSearchScope scope = StringUtils.isNotEmpty(mn) ? GlobalSearchScope.moduleScope(ProjectUtils.getModuleWithName(project, mn)) : GlobalSearchScope.projectScope(project); + Query query = AllClassesSearch.search(scope, project, s -> s.endsWith(end)); + Collection classes = query.findAll(); + return classes.stream().map(it -> { + String name = it.getQualifiedName(); + String moduleName = PsiClassUtils.getModule(project, it).getName(); + return ClassInfo.builder().className(name).moduleName(moduleName).build(); + }).collect(Collectors.toList()); + } + + private static String findPomDependencies(String basePath, String groupId, String artifactId, String version) throws IOException { + File baseDir = new File(basePath); + String[] extensions = {"xml"}; + boolean recursive = true; + + Collection pomFiles = FileUtils.listFiles(baseDir, extensions, recursive); + for (File pomFile : pomFiles) { + try { + MavenXpp3Reader reader = new MavenXpp3Reader(); + Model model = reader.read(new FileReader(pomFile)); + List dependencies = model.getDependencies(); + for (Dependency dependency : dependencies) { + if (dependency.getGroupId().equals(groupId) && + dependency.getArtifactId().equals(artifactId) && + dependency.getVersion().equals(version)) { + // 找到了指定的依赖项 + return "找到了"; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return "没找到"; + } + + /** + * 获取方法的注释 + * + * @param psiMethod + * @return + */ + public static String getMethodComment(PsiMethod psiMethod) { + PsiDocComment comment = psiMethod.getDocComment(); + if (comment != null) { + return comment.getText(); + } + return null; + } + + /** + * 获取属性的注释 + * + * @param psiField + * @return + */ + public static String getFieldComment(PsiField psiField) { + PsiDocComment comment = psiField.getDocComment(); + if (comment != null) { + return comment.getText(); + } + return ""; + } + + public static ImportCode createClassAndAddEmptyLine(Project project, String module, String packageName, String className, String classNameSuffix, boolean isTestClass, boolean isInterface) { + String qualifiedName = packageName + "." + className; + + PsiClass openJavaClass = CodeService.openJavaClass(project, qualifiedName + classNameSuffix); + if (null == openJavaClass) { + CodeService.createEmptyClass(project, module, packageName, className + classNameSuffix, isTestClass, isInterface); + openJavaClass = CodeService.openJavaClass(project, qualifiedName + classNameSuffix); + } + + Editor editor = CodeService.getEditor(project); + addEmptyLine(project, openJavaClass, editor); + + ImportCode importCode = new ImportCode(); + importCode.setProject(project); + importCode.setEditor(editor); + return importCode; + } + + private static void addEmptyLine(Project project, PsiClass openJavaClass, Editor editor) { + PsiMethod @NotNull [] methods = openJavaClass.getMethods(); + int offset = 0; + if (0 == methods.length) { + offset = openJavaClass.getTextRange().getEndOffset() - 3; + } else { + PsiMethod psiMethod = methods[methods.length - 1]; + offset = psiMethod.getTextRange().getEndOffset(); + } + editor.getCaretModel().moveToOffset(offset); + CodeService.writeCode2(project, editor, "\n"); + + } + + public static void tryParserBasedFix(String code, String projectName, String className) { + if (StringUtils.isBlank(code)) { + log.warn("empty code detected, projectName:{}, className:{}", projectName, className); + return; + } + AthenaClassInfo athenaClassInfo = AthenaCodeService.classInfoWithDetail(code, true); + Project project = ProjectUtils.projectFromManager(projectName); + PsiClass psiClass = PsiClassUtils.findClassByName(project, className); + // TODO: 根据className pattern制定fix规则 + M78Visitor m78Visitor = new M78Visitor(); + m78Visitor.setMissedImports(ImmutableList.of("org.bson.Document", "dev.morphia.annotations.Id")); + m78Visitor.setWildCardImportPackages(ImmutableList.of("java.util")); + psiClass.getParent().accept(m78Visitor); + // PsiClassFixer.fixUndefinedMethods(psiClass, project); + } + + public static void tryQuickFix(String code, JsonObject obj, String projectName, String className) { + if (StringUtils.isBlank(code)) { + log.warn("calling fix code with req:{}, but code is not generated yet, will do nothing...", obj); + return; + } + Project project = ProjectUtils.projectFromManager(projectName); + PsiClass psiClass = PsiClassUtils.findClassByName(project, className); + if (psiClass == null) { + log.warn("unable to find className:{} in project:{}, will quit quick fix...", className, projectName); + return; + } + PsiFile file = psiClass.getContainingFile(); + if (file == null) { + log.warn("unable to find psi file for className:{} in project:{}, will quit quick fix...", className, projectName); + return; + } + ApplicationManager.getApplication().invokeLater(() -> QuickFixInvokeUtil.quickFix2(project, file)); + } + + @Override + public void next(Context context, AnActionEvent e) { + super.next(context, e); + } + + public static T invoke(Supplier supplier) { + MutableObject mo = new MutableObject(); + ApplicationManager.getApplication().invokeAndWait(() -> { + Object obj = supplier.get(); + mo.setValue(obj); + }); + return (T) mo.getValue(); + } + + public static void invokeLater(Runnable runnable) { + ApplicationManager.getApplication().invokeLater(() -> runnable.run()); + } +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/DocumentService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/DocumentService.java new file mode 100644 index 000000000..5d7182480 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/DocumentService.java @@ -0,0 +1,107 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 com.xiaomi.youpin.tesla.ip.service; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.impl.EditorImpl; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import org.apache.commons.lang.mutable.MutableObject; +import org.apache.commons.lang3.tuple.Pair; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/6 12:08 + */ +public class DocumentService { + + private static final Logger log = Logger.getInstance(DocumentService.class); + + /** + * 用ide打开文件 + * @param name + * @param text + */ + public void open(String name, String text) { + log.info("open file"); + Project project = ProjectManager.getInstance().getOpenProjects()[0]; + FileEditorManagerEx fileEditorManager = FileEditorManagerEx.getInstanceEx(project); + try { + Files.write(Paths.get("/tmp/" + name), text.getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + (new WriteCommandAction.Simple(project) { + @Override + protected void run() { + VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath("/tmp/" + name); + fileEditorManager.openFile(file, false); + } + }).execute(); + } + + /** + * 获取文件内容和文件名(content,fileName) + * @param anActionEvent + * @return + */ + public Pair getContent(AnActionEvent anActionEvent) { + log.info("get content"); + Editor editor = null; + if (null == anActionEvent) { + MutableObject mo = new MutableObject(); + ApplicationManager.getApplication().invokeAndWait(()->{ + Project project = ProjectManager.getInstance().getOpenProjects()[0]; + Editor e = FileEditorManager.getInstance(project).getSelectedTextEditor(); + mo.setValue(e); + }); + editor = (Editor) mo.getValue(); + } else { + editor = anActionEvent.getRequiredData(CommonDataKeys.EDITOR); + } + + if (null == editor) { + return null; + } + + String name = "tmp.java"; + if (editor instanceof EditorImpl) { + EditorImpl ei = (EditorImpl) editor; + name = ei.getVirtualFile().getName(); + System.out.println(name); + } + + Document document = editor.getDocument(); + String text = document.getText(); + return Pair.of(text, name); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/EditorService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/EditorService.java similarity index 85% rename from athena-all/src/main/java/run/mone/m78/ip/service/EditorService.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/EditorService.java index 84ca1dac1..a44e4d5de 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/EditorService.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/EditorService.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.service; +package com.xiaomi.youpin.tesla.ip.service; import com.intellij.openapi.editor.Editor; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/GuideService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/GuideService.java new file mode 100644 index 000000000..4273e356b --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/GuideService.java @@ -0,0 +1,464 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import cn.hutool.core.bean.BeanUtil; +import com.google.common.base.Splitter; +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.RefreshQueue; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.impl.source.PsiMethodImpl; +import com.xiaomi.youpin.tesla.ip.bo.*; +import com.xiaomi.youpin.tesla.ip.bo.z.EmbeddingStatus; +import com.xiaomi.youpin.tesla.ip.common.ConfigCenter; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.listener.Req; +import com.xiaomi.youpin.tesla.ip.ui.VersionUi; +import com.xiaomi.youpin.tesla.ip.util.*; +import org.apache.commons.compress.utils.Lists; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableInt; +import org.apache.commons.lang3.mutable.MutableObject; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.bo.CodeReq; +import run.mone.ultraman.bo.Version; +import run.mone.ultraman.common.ActionEventUtils; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.common.TestRunnerUtils; +import run.mone.ultraman.http.HttpClient; +import run.mone.ultraman.service.AthenaCodeService; +import run.mone.ultraman.service.ModuleService; +import run.mone.ultraman.state.ProjectFsmManager; + +import java.io.File; +import java.util.Arrays; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2024/6/24 14:02 + */ +public class GuideService { + + private static Gson gson = GsonUtils.gson; + + private static ExecutorService pool = Executors.newSingleThreadExecutor(); + + /** + * AI引导方法,根据请求参数中的问题,获取相应的提示信息列表 + * + * @param req 请求参数对象,包含问题信息 + * @return 返回提示信息列表的JSON字符串 + */ + public static String aiGuide(Req req, Project project) { + AiCodeRes res = new AiCodeRes(); + String question = req.getData().get("question"); + if (question.equals("flush")) { + Prompt.flush(); + res.setMsg("flush success"); + return gson.toJson(res); + } + + if (question.startsWith("invoke_code:")) { + List list = Splitter.on(":").splitToList(question); + if (list.size() == 4) { + String codeName = list.get(1); + String method = list.get(2); + String param = list.get(3); + Object codeRes = ScriptService.ins().invoke(ScriptService.getScript(codeName), method, Maps.newHashMap(), param); + res.setMsg("invoke code success:" + codeRes); + } else { + res.setMsg(list + " list size != 4"); + } + return gson.toJson(res); + } + + //添加一个功能(entity mapper service controller),调用的事flow + if (question.startsWith("feature:")) { + callFlow(question, "256", project.getName(), new JsonObject()); + return gson.toJson(res); + } + + //添加一个功能(entity mapper service controller),调用的事flow (主要通过调用本地模板) + if (question.startsWith("feature2:")) { + String className = ApplicationManager.getApplication().runReadAction((Computable) () -> { + PsiClass psiClass = CodeService.getPsiClass(project); + return psiClass.getQualifiedName(); + }); + JsonObject object = new JsonObject(); + object.addProperty("codeGenClassName", className); + callFlow(question, "30016", project.getName(), object); + return gson.toJson(res); + } + + //生成单元测试类 + if (question.startsWith("cjunit")) { + ApplicationManager.getApplication().invokeLater(() -> { + List list = AnnoUtils.findClassWithAnno(project, "com.xiaomi.youpin.docean.anno.Service", null); + System.out.println(list); + list.stream().limit(3).forEach(ci -> { + String className = "run.mone.test.service." + ci.getSimpleName() + "Test"; + PsiClass psiClass = PsiClassUtils.findClassByName(project, className); + if (null != psiClass) { + return; + } + //创建这个PsiClass + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("testName", ci.getSimpleName() + "Test"); + jsonObject.addProperty("pojoName", ci.getSimpleName().replace("Service", "")); + String param = new String(Base64.getEncoder().encode(GsonUtils.gson.toJson(jsonObject).getBytes())); + ActionEventUtils.setupAndExecuteJavaAppConfiguration("run.mone.test.service.CodeGen", param, ProjectUtils.projectFromManager(project.getName())); + }); + }); + return gson.toJson(res); + } + + //直接生成单元测试(所有service直接生成单元测试) + if (question.startsWith("junit")) { + ApplicationManager.getApplication().invokeLater(() -> { + //查找到所有Service类 + List list = AnnoUtils.findClassWithAnno(project, "com.xiaomi.youpin.docean.anno.Service", null); + list.stream().forEach(ci -> { + String testClassName = "run.mone.test.service." + ci.getSimpleName() + "Test"; + //查看这个测试类是否存在,如果存在则直接跳过 + PsiClass psiClass = PsiClassUtils.findClassByName(project, testClassName); + if (null != psiClass) { + //获取单元测试的 + List methods = getNonConstructorMethodTexts(psiClass); + if (!methods.isEmpty()) { + return; + } + + //获取需要测试的那个类 + PsiClass pc = PsiClassUtils.findClassByName(project, ci.getClassName()); + if (null == pc) { + return; + } + + //获取实际要测试的类的方法集合 + @NotNull List mList = getNonConstructorMethodTexts(pc); + if (mList.isEmpty()) { + return; + } + + //保障单线程执行,一起操作ide,和一起操作ws都是有问题的 + pool.submit(() -> { + Mutable> mutable = new MutableObject<>(); + ApplicationManager.getApplication().invokeAndWait(()->{ + String testClassCode = PromptUtils.openUnitTestClass(project, testClassName); + Editor editor = CodeService.getEditor(project); + mutable.setValue(Pair.of(testClassCode, editor)); + }); + + String testClassCode = mutable.getValue().getKey(); + Editor editor = mutable.getValue().getValue(); + + mList.forEach(mText -> { + CountDownLatch latch = new CountDownLatch(1); + PromptUtils.generateUnitTest(project, mText, testClassName, new HashMap<>(), testClassCode, editor, latch); + try { + latch.await(20, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + //插入换行 + CodeService.writeCode2(project, editor, "\n\n"); + }); + + }); + + } + + }); + + + }); + return gson.toJson(res); + } + + //bug fix,调用的事flow + if (question.startsWith("fix")) { + JsonObject jo = new JsonObject(); + JsonObject input = new JsonObject(); + ApplicationManager.getApplication().invokeLater(() -> { + PsiMethod psiMethod = CodeService.getMethod(project); + TestRunnerUtils.runTest(project, psiMethod.getName(), pair -> { + //用来存储错误信息 + input.addProperty("input", pair.getValue()); + input.addProperty("host", AthenaContext.ins().getLocalAddress()); + input.addProperty("port", AthenaContext.ins().getLocalPort()); + input.addProperty("projectName", project.getName()); + jo.add("input", input); + + jo.addProperty("userName", AthenaContext.ins().getUserName()); + jo.addProperty("flowId", "60014"); + new Thread(() -> HttpClient.post("https://xxx", jo.toString())).start(); + }); + }); + return gson.toJson(res); + } + + if (question.startsWith("test")) { + ApplicationManager.getApplication().invokeLater(() -> PsiMethodUtils.extractMethodCallParts(project, CodeService.getEditor(project))); + return gson.toJson(res); + } + + if (question.startsWith("model")) { + List list = Splitter.on(":").splitToList(question); + if (list.size() == 2) { + AthenaContext.ins().setGptModel(list.get(1)); + res.setMsg("set model success model:" + list.get(1)); + } + return gson.toJson(res); + } + + if (question.startsWith("aidebug")) { + List list = Splitter.on(":").splitToList(question); + if (list.size() == 2) { + AthenaContext.ins().setDebugAiProxy(Boolean.valueOf(list.get(1))); + res.setMsg("ai debug:" + list.get(1)); + } + return gson.toJson(res); + } + + if (question.equals("refreshconfig")) { + ResourceUtils.getAthenaConfig(project, true); + res.setMsg("refresh config success"); + return gson.toJson(res); + } + + //获取作者信息 + if (question.equals("author")) { + return author(res); + } + + if (question.startsWith("troubleshoot")) { + RobotService.troubleshoot(null, RobotReq.builder().project(project).param(question).build()); + return ""; + } + + //获取embedding 信息 + if (question.equals("embedding_status")) { + return embeddingStatus(req, res, project); + } + + //打开配置 + if (question.equals("config")) { + ApplicationManager.getApplication().invokeLater(() -> LabelUtils.showLabelConfigUi(project)); + res.setMsg("show config success"); + return gson.toJson(res); + } + + if (question.equals("collected")) { + res.setMsg(" "); + res.setPromptInfoList(buildAiCodePromptRes(Prompt.getCollected())); + return gson.toJson(res); + } + + if (question.equals("debug")) { + res.setMsg(new Version().toString()); + return gson.toJson(res); + } + + //刷新业务代码到知识库 + if (question.equals("flush_biz")) { + return flushBizCode(req, res, project); + } + + if (question.equals("class_len")) { + return getClassLen(res, project); + } + + //停止状态机 + if (question.equals("stop")) { + ProjectFsmManager.stop(project.getName()); + res.setMsg("退出状态机"); + return gson.toJson(res); + } + + //git 代码push + if (question.equals("push")) { + PromptInfo promptInfo = Prompt.getPromptInfo("bot_call"); + ApplicationManager.getApplication().invokeLater(() -> PromptService.dynamicInvoke(GenerateCodeReq.builder().promptInfo(promptInfo).project(project).promptType(PromptType.executeBot).build())); + res.setMsg("push"); + return gson.toJson(res); + } + + //代码review + if (question.equals("review")) { + PromptInfo promptInfo = Prompt.getPromptInfo("bot_stream"); + ApplicationManager.getApplication().invokeLater(() -> PromptService.dynamicInvoke(GenerateCodeReq.builder().promptInfo(promptInfo).project(project).promptType(PromptType.executeBot).build())); + res.setMsg("review"); + return gson.toJson(res); + } + + //查询状态机状态 + if (question.equals("state")) { + String state = ProjectFsmManager.state(project.getName()); + res.setMsg("state:" + state); + return gson.toJson(res); + } + + //测试prompt + if (question.startsWith("prompt:")) { + String promptName = question.split(":")[1]; + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + PromptType promptType = Prompt.getPromptType(promptInfo); + ApplicationManager.getApplication().invokeLater(() -> { + PromptService.testPrompt(GenerateCodeReq.builder().project(project) + .promptName(promptName).promptInfo(promptInfo).promptType(promptType).build()); + }); + res.setMsg("ok"); + return gson.toJson(res); + } + + AiCodeRes cache = ConfigCenter.build(question); + if (null == cache) { + res.setMsg(Message.unsupportedCommand); + return gson.toJson(res); + } + res.setMsg(cache.getMsg()); + if (!"help".equals(question)) { + List promptRes = Lists.newArrayList(); + List promptList = Prompt.getPromptInfoByTag(cache.getTagName()); + promptRes.addAll(cache.getPromptInfoList()); + promptRes.addAll(buildAiCodePromptRes(promptList)); + res.setPromptInfoList(promptRes); + } else { + res.setPromptInfoList(cache.getPromptInfoList()); + } + return gson.toJson(res); + } + + @NotNull + private static List getNonConstructorMethodTexts(PsiClass psiClass) { + return Arrays.stream(psiClass.getMethods()).filter(it2 -> { + if (it2 instanceof PsiMethodImpl && !it2.isConstructor()) { + return true; + } + return false; + }).map(PsiElement::getText).collect(Collectors.toList()); + } + + private static void callFlow(String question, String flowId, String projectName, JsonObject jsonObject) { + List list = Splitter.on(":").splitToList(question); + JsonObject jo = new JsonObject(); + JsonObject input = new JsonObject(); + input.addProperty("input", list.get(1)); + input.addProperty("host", AthenaContext.ins().getLocalAddress()); + input.addProperty("port", AthenaContext.ins().getLocalPort()); + input.addProperty("projectName", projectName); + + jsonObject.keySet().forEach(key -> input.addProperty(key, jsonObject.get(key).getAsString())); + + jo.add("input", input); + jo.addProperty("userName", AthenaContext.ins().getUserName()); + jo.addProperty("flowId", flowId); + //异步化调用 + new Thread(() -> HttpClient.post("https://xx", jo.toString())).start(); + } + + + //获取当前打开类的长度 + private static String getClassLen(AiCodeRes res, Project project) { + MutableInt num = new MutableInt(); + ApplicationManager.getApplication().invokeAndWait(() -> { + String text = CodeService.getClassText(project); + num.setValue(text.length()); + }); + res.setMsg(String.valueOf(num.getValue())); + return gson.toJson(res); + } + + //获取作者信息 + private static String author(AiCodeRes res) { + ApplicationManager.getApplication().invokeLater(() -> { + VersionUi versionUi = new VersionUi(); + versionUi.show(); + }); + res.setMsg(new Version().toString()); + return gson.toJson(res); + } + + private static void refreshProject(String targetExtractionDir) { + VirtualFile targetFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(targetExtractionDir)); + RefreshQueue.getInstance().refresh(false, true, null, targetFile); + } + + private static List buildAiCodePromptRes(List promptInfoList) { + List list = promptInfoList.stream().filter(p -> p.getTags().stream().anyMatch(tag -> tag.getName().equals("plugin"))).map(promptInfo -> { + AiCodePromptRes promptRes = new AiCodePromptRes(); + BeanUtil.copyProperties(promptInfo, promptRes); + promptRes.setType("cmd"); + promptRes.setShowDialog(promptInfo.getLabels().getOrDefault("showDialog", "false")); + return promptRes; + }).collect(Collectors.toList()); + return list; + } + + //刷新业务代码到知识库 + private static String flushBizCode(Req req, AiCodeRes res, Project project) { + String moduleName = req.getData().get("module"); + String scope = req.getData().get("scope"); + ApplicationManager.getApplication().invokeLater(() -> { + if ("project".equals(scope)) { + //Refresh all modules. + List list = ProjectUtils.listAllModules(project).stream().filter(it -> !it.equals(req.getData().get("project"))).collect(Collectors.toList()); + list.stream().forEach(it -> ModuleService.uploadModelText(project, getModule(it, project))); + } else { + ModuleService.uploadModelText(project, getModule(moduleName, project)); + } + }); + res.setMsg("flush biz success"); + return gson.toJson(res); + } + + private static String embeddingStatus(Req req, AiCodeRes res, Project project) { + String scope = req.getData().getOrDefault("scope", "project"); + CodeReq.CodeReqBuilder builder = CodeReq.builder(); + builder.projectName(project.getName()); + if (!scope.equals("project")) { + builder.moduleName(getModule(req.getData().get("module"), project).getName()); + } + EmbeddingStatus status = AthenaCodeService.embeddingStatus(builder.build()); + String msg = scope.equals("project") ? ("project_" + req.getData().get("project")) : ("module_" + req.getData().get("module")); + res.setMsg(gson.toJson(status) + ":" + msg); + return gson.toJson(res); + } + + @Nullable + private static Module getModule(String moduleName, Project project) { + if (StringUtils.isEmpty(moduleName)) { + Mutable mutable = new MutableObject<>(); + ApplicationManager.getApplication().invokeAndWait(() -> { + mutable.setValue(ProjectUtils.getCurrentModule(project)); + }); + return mutable.getValue(); + } else { + return ProjectUtils.getModuleWithName(project, moduleName); + } + + + } +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/LocalAiService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/LocalAiService.java new file mode 100644 index 000000000..58f6daa4d --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/LocalAiService.java @@ -0,0 +1,520 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import cn.hutool.core.codec.Base64; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.xiaomi.youpin.tesla.ip.bo.*; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.Message; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.*; +import com.xiaomi.youpin.tesla.ip.bo.robot.AiChatMessage; +import com.xiaomi.youpin.tesla.ip.bo.robot.MessageType; +import com.xiaomi.youpin.tesla.ip.bo.robot.ProjectAiMessageManager; +import com.xiaomi.youpin.tesla.ip.bo.robot.Role; +import com.xiaomi.youpin.tesla.ip.common.ChromeUtils; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.NotificationCenter; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.util.ProjectUtils; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import okhttp3.Response; +import okhttp3.*; +import okhttp3.sse.EventSource; +import okhttp3.sse.EventSourceListener; +import okhttp3.sse.EventSources; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import run.mone.openai.OpenaiCall; +import run.mone.openai.ReqConfig; +import run.mone.openai.StreamListener; +import run.mone.ultraman.AthenaInspection; +import run.mone.ultraman.background.AthenaTask; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.state.ProjectFsmManager; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/11/23 13:56 + *

+ * 这个类允许你本地直连chatgpt(如果是国内的网络需要设置open_ai_proxy) + */ +@Slf4j +public class LocalAiService { + + + private static String getOpenAiUrl() { + String url = ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_PROXY, ""); + if (StringUtils.isEmpty(url)) { + return "https://api.openai.com/v1/"; + } + return url; + } + + + /** + * 调用chatgpt的语音翻译(你需要有chatgpt的账号) + * + * @param file + * @return + */ + @SneakyThrows + public static Pair callChatgptTranscriptions(File file) { + String apiKey = ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_KEY, ""); + + if (StringUtils.isEmpty(apiKey)) { + return Pair.of(500, "在环境变量中设置:OPENAI_API_KEY"); + } + + + RequestBody requestBody = RequestBody.create(MediaType.parse("audio/mpeg"), file); + + MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder(); + multipartBodyBuilder.setType(MultipartBody.FORM); + multipartBodyBuilder.addFormDataPart("file", "openai.mp3", requestBody); + multipartBodyBuilder.addFormDataPart("model", "whisper-1"); + + Request request = new Request.Builder() + .url(getOpenAiUrl() + "/audio/transcriptions") + .post(multipartBodyBuilder.build()) + .addHeader("Authorization", "Bearer " + apiKey) + .addHeader("Content-Type", "multipart/form-data") + .build(); + + OkHttpClient client = new OkHttpClient(); + + Response response = client.newCall(request).execute(); + + if (response.code() == 200) { + AudioRes res = new Gson().fromJson(response.body().string(), AudioRes.class); + return Pair.of(0, res.getText()); + } + + return Pair.of(500, ""); + } + + + /** + * 直接把文字转成语音 + * + * @param req + * @return + */ + @SneakyThrows + public static Pair speech(SpeechReq req) { + String apiKey = ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_KEY, ""); + if (StringUtils.isEmpty(apiKey)) { + return Pair.of(500, "在环境变量中设置:OPENAI_API_KEY"); + } + OkHttpClient client = new OkHttpClient().newBuilder() + .build(); + MediaType mediaType = MediaType.parse("application/json"); + RequestBody body = RequestBody.create(mediaType, new Gson().toJson(req)); + Request request = new Request.Builder() + .url(getOpenAiUrl() + "/audio/speech") + .method("POST", body) + .addHeader("Authorization", "Bearer " + apiKey) + .addHeader("Content-Type", "application/json") + .build(); + Response response = client.newCall(request).execute(); + + if (response.code() == 200) { + byte[] saveData = response.body().bytes(); + Files.write(Paths.get("/tmp/sp.mp3"), saveData); + return Pair.of(0, Base64.encode(saveData)); + } + + return Pair.of(500, ""); + + } + + + //多模态调用(支持图片) + public static String vision(VisionReq req) { + String apiKey = ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_KEY, ""); + if (StringUtils.isEmpty(apiKey)) { + return ""; + } + OkHttpClient client = new OkHttpClient().newBuilder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(10, TimeUnit.SECONDS) + .build(); + MediaType mediaType = MediaType.parse("application/json"); + RequestBody body = RequestBody.create(mediaType, new Gson().toJson(req)); + Request request = new Request.Builder() + .url(getOpenAiUrl() + "/chat/completions") + .method("POST", body) + .addHeader("Content-Type", "application/json") + .addHeader("Authorization", "Bearer " + apiKey) + .build(); + try { + Response response = client.newCall(request).execute(); + String str = response.body().string(); + VisionRes visionRes = new Gson().fromJson(str, VisionRes.class); + System.out.println(visionRes.getChoices().get(0)); + return visionRes.getChoices().get(0).getMessage().getContent(); + } catch (IOException e) { + e.printStackTrace(); + } + return ""; + } + + + public static JsonObject call(List messageList) { + Completions completions = Completions.builder() + .stream(false) + .response_format(Format.builder().build()).messages(messageList).build(); + String req = GsonUtils.gson.toJson(completions); + return call(req); + } + + + public static JsonObject call(String req) { + return call(req, 5000); + } + + //这个会直接调用chatgpt + @SneakyThrows + public static JsonObject call(String req, long timeout) { + long time = timeout; + for (int i = 1; i <= 3; i++) { + time = time * i; + log.info("call gpt req:{} timeout:{}", req, timeout); + String apiKey = ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_KEY, ""); + if (StringUtils.isEmpty(apiKey)) { + return null; + } + OkHttpClient client = new OkHttpClient.Builder() + .connectTimeout(time, TimeUnit.MILLISECONDS) + .readTimeout(time, TimeUnit.MILLISECONDS) + .build(); + + MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); + + Request request = new Request.Builder() + .url(getOpenAiUrl() + "/chat/completions") + .addHeader("Content-Type", "application/json") + .addHeader("Authorization", "Bearer " + apiKey) + .post(RequestBody.create(mediaType, req.getBytes(Charset.forName("utf8")))) + .build(); + + try (Response response = client.newCall(request).execute()) { + // 判断请求是否成功 + if (response.isSuccessful() && response.body() != null) { + String responseBody = response.body().string(); + return parseJson(responseBody); + } else { + System.err.println("Request failed: " + response.code()); + } + } catch (IOException e) { + e.printStackTrace(); + TimeUnit.SECONDS.sleep(1); + } + } + return null; + } + + + //直接问问题(直接调用chatgpt) + public static void completions(String req, StreamListener sl) { + String apiKey = ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_KEY, ""); + if (StringUtils.isEmpty(apiKey)) { + return; + } + MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); + + Request request = new Request.Builder() + .url(getOpenAiUrl() + "/chat/completions") + .addHeader("Content-Type", "application/json") + .addHeader("Authorization", "Bearer " + apiKey) + .post(RequestBody.create(mediaType, req.getBytes(Charset.forName("utf8")))) + .build(); + + OkHttpClient client = new OkHttpClient.Builder() + .connectTimeout(5000, TimeUnit.MILLISECONDS) + .readTimeout(5000, TimeUnit.MILLISECONDS) + .build(); + + + EventSourceListener listener = new EventSourceListener() { + + @Override + public void onOpen(EventSource eventSource, Response response) { + log.info("onOpen"); + sl.begin(); + } + + @Override + public void onEvent(EventSource eventSource, String id, String type, String data) { + data = parse(data); + sl.onEvent(data); + } + + @Override + public void onClosed(EventSource eventSource) { + log.info("onClosed"); + sl.end(); + } + + @Override + public void onFailure(EventSource eventSource, Throwable t, Response response) { + log.info("onFailure response:" + response, t); + sl.onFailure(t, response); + sl.end(); + } + }; + + EventSource.Factory factory = EventSources.createFactory(client); + factory.newEventSource(request, listener); + } + + + private static String parse(String data) { + log.info(data); + if (data.equals("[DONE]")) { + return ""; + } + try { + JSONArray choices = JSON.parseObject(data).getJSONArray("choices"); + if (choices.isEmpty()) { + return ""; + } + + String obj = choices.getJSONObject(0).getJSONObject("delta").getString("content"); + if (null != obj) { + return obj; + } + return ""; + } catch (Throwable ex) { + log.error(ex.getMessage(), ex); + } + return ""; + } + + private static JsonObject parseJson(String data) { + log.info("data:{}", data); + JsonObject obj = GsonUtils.gson.fromJson(data, JsonObject.class); + JsonArray choices = obj.getAsJsonArray("choices"); + return GsonUtils.gson.fromJson(choices.get(0).getAsJsonObject().getAsJsonObject("message").get("content").getAsString(), JsonObject.class); + } + + //本地直接调用chatgpt,单条提问 + public static void localCall(Project project, String prompt) { + localCall(project, Lists.newArrayList(Message.builder().content(prompt).role("user").build()), false, 0); + } + + + public static void localCall(String projectName, boolean code) { + log.info("question call prompt"); + List> list = ProjectAiMessageManager.getInstance().getMessageList(projectName); + //转换为Message + List newMessageList = list.stream().map(it -> Message.builder().role(it.getRole().name()).content(it.toString()).build()).peek(it -> { + log.info("---->role:{} content:{}", it.getRole(), it.getContent()); + }).collect(Collectors.toList()); + String id = UUID.randomUUID().toString(); + chat(ProjectUtils.projectFromManager(projectName), code, newMessageList, projectName, id); + } + + + //目前是从前端拿到的,这个需要自己记录,这样以后能完成的事情更多 + public static void localCall(Project project, List messageList, boolean code, int num) { + //这是前端传过来的(以后只信任最后一条) + Message msg = messageList.get(messageList.size() - 1); + + boolean process = ProjectFsmManager.processMsg(project.getName(), msg.getContent()); + if (process) { + return; + } + + //这就是自己维护的那份消息列表(这里的id是判断这个msg的时候返回给前端的) + List> list = ProjectAiMessageManager.getInstance().addMessage(project, + AiChatMessage.builder() + .message(msg.getContent()) + .type(MessageType.string) + .data(msg.getContent()) + .id(msg.getId()) + .role(Role.user) + .build()); + + //转换为Message + List newMessageList = list.stream().map(it -> Message.builder().role(it.getRole().name()).content(it.toString()).build()).peek(it -> { + log.info("---->role:{} content:{}", it.getRole(), it.getContent()); + }).collect(Collectors.toList()); + + //取最后的一部分 + if (num != 0) { + newMessageList = getLastElements(newMessageList, num); + } + + + String projectName = project.getName(); + String msgId = UUID.randomUUID().toString(); + + // TODO 直接调用BOT + if("true".equals(ResourceUtils.get(Const.CONF_CHAT_USE_BOT, "true"))) { + Map param = new HashMap<>(); + param.put("chatContent", msg.getContent()); + AthenaInspection.invokePrompt(project, Const.ATHENA_CHAT, param); + return; + } + + //调用ai proxy + if (LabelUtils.open(project, Const.AI_PROXY_CHAT, "true")) { + aiProxyChat(project, newMessageList); + return; + } + + //直接本地调用 + chat(project, code, newMessageList, projectName, msgId); + } + + + public static List getLastElements(List list, int num) { + if (list == null || list.isEmpty() || num <= 0) { + return Collections.emptyList(); + } + int startIndex = Math.max(list.size() - num, 0); + return list.subList(startIndex, list.size()); + } + + private static void chat(Project project, boolean code, List newMessageList, String projectName, String id) { + ApplicationManager.getApplication().invokeLater(() -> AthenaTask.start(new Task.Backgroundable(project, "chat", true) { + @SneakyThrows + @Override + public void run(@NotNull ProgressIndicator indicator) { + String model = ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_MODEL, "gpt-3.5-turbo"); + Completions completions = Completions.builder().model(model).messages(newMessageList).build(); + CountDownLatch latch = new CountDownLatch(1); + StringBuilder sb = new StringBuilder(); + LocalAiService.completions(GsonUtils.gson.toJson(completions), new StreamListener() { + + @Override + public void begin() { + AiMessage msg = AiMessage.builder().projectName(projectName).code(code).type(AiMessageType.begin).id(id).build(); + sendMsg(msg, projectName); + } + + @Override + public void onEvent(String str) { + AiMessage msg = AiMessage.builder().projectName(projectName).type(AiMessageType.process).id(id).text(str).build(); + sendMsg(msg, projectName); + sb.append(msg.getText()); + } + + + @Override + public void end() { + latch.countDown(); + AiMessage msg = AiMessage.builder().projectName(projectName).type(AiMessageType.success).id(id).build(); + sendMsg(msg, projectName); + String str = sb.toString(); + ProjectAiMessageManager.getInstance().addMessage(project, + AiChatMessage.builder().id(id).message(str).data(str).type(MessageType.string).role(Role.assistant).build()); + } + }); + latch.await(15, TimeUnit.SECONDS); + } + })); + } + + + //调用ai proxy(进行聊天) + private static void aiProxyChat(Project project, List newMessageList) { + ApplicationManager.getApplication().invokeLater(() -> AthenaTask.start(new Task.Backgroundable(project, "Athena", true) { + @SneakyThrows + @Override + public void run(@NotNull ProgressIndicator indicator) { + CountDownLatch latch = new CountDownLatch(1); + String projectName = project.getName(); + List msgList = newMessageList.stream().map(it -> { + Msg msg = new Msg(); + msg.setContent(it.getContent()); + msg.setRole(it.getRole().toUpperCase()); + return msg; + }).collect(Collectors.toList()); + try { + ProxyAsk pa = new ProxyAsk(); + pa.setMsgList(msgList); + pa.setType(1); + pa.setFrom("chat"); + CodeService.setModelAndDebug(project, pa, Maps.newHashMap(), GenerateCodeReq.builder().project(project).build()); + String id = UUID.randomUUID().toString(); + pa.setId(id); + pa.setZzToken(ConfigUtils.getConfig().getzToken()); + OpenaiCall.callStream2(GsonUtils.gson.toJson(pa), new StreamListener() { + + StringBuilder sb = new StringBuilder(); + + @Override + public void begin() { + AiMessage msg = AiMessage.builder().projectName(projectName).code(false).type(AiMessageType.begin).id(id).build(); + sendMsg(msg, projectName); + } + + @Override + public void onEvent(String str) { + str = new String(java.util.Base64.getDecoder().decode(str.getBytes(Charset.forName("utf8"))), Charset.forName("utf8")); + AiMessage msg = AiMessage.builder().projectName(projectName).type(AiMessageType.process).id(id).text(str).build(); + sendMsg(msg, projectName); + sb.append(msg.getText()); + } + + @Override + public void onFailure(Throwable t, Response response) { + NotificationCenter.notice("调用ai proxy发生了错误:" + t.getMessage(), NotificationType.ERROR); + } + + @Override + public void end() { + latch.countDown(); + AiMessage msg = AiMessage.builder().projectName(projectName).type(AiMessageType.success).id(id).build(); + sendMsg(msg, projectName); + String str = sb.toString(); + ProjectAiMessageManager.getInstance().addMessage(project, + AiChatMessage.builder().id(id).message(str).data(str).type(MessageType.string).role(Role.assistant).build()); + } + }, ReqConfig.builder().connectTimeout(TimeUnit.SECONDS.toMillis(10)).readTimeout(TimeUnit.SECONDS.toMillis(30)).maxTokens(4000).askUrl(ConfigUtils.getConfig().getAiProxy() + "/ask").build()); + } catch (Throwable ex) { + log.error(ex.getMessage(), ex); + } + latch.await(1, TimeUnit.MINUTES); + } + })); + + + } + + //每次都只发一部分(发送到右侧 athena) + public static void sendMsg(AiMessage message, String projectName) { + String str = GsonUtils.gson.toJson(message); + ChromeUtils.call(projectName, "setResultCode", str); + } + + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/M78Service.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/M78Service.java new file mode 100644 index 000000000..49ff0e22f --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/M78Service.java @@ -0,0 +1,79 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import com.google.common.base.Stopwatch; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; +import com.intellij.openapi.project.Project; +import com.xiaomi.youpin.infra.rpc.Result; +import com.xiaomi.youpin.tesla.ip.bo.AiMessage; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; +import lombok.extern.slf4j.Slf4j; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.common.ImportCode; +import run.mone.ultraman.http.HttpClient; +import run.mone.ultraman.http.WsClient; + +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Consumer; + +/** + * @author HawickMason@xiaomi.com + * @date 6/6/24 16:22 + */ +@Slf4j +public class M78Service { + + public static Result speechToText2(JsonObject jsonObject) { + Map athenaConfig = ResourceUtils.getAthenaConfig(); + String apiSpeechToText2 = athenaConfig.get(Const.CONF_M78_URL) + + athenaConfig.get(Const.CONF_M78_SPEECH2TEXT); + String param = jsonObject.toString(); + log.info("calling:{}, param:{}", apiSpeechToText2, param); + String resp = HttpClient.callHttpServer(apiSpeechToText2, "callM78SpeechToText2", param, false, false, 30); + Result res = GsonUtils.gson.fromJson(resp, new TypeToken>() {}.getType()); + log.info("calling:{}, resCode:{}", apiSpeechToText2, res.getCode()); + return res; + } + + public static Result textToSpeech(JsonObject jsonObject) { + Map athenaConfig = ResourceUtils.getAthenaConfig(); + String apiTextToSpeech = athenaConfig.get(Const.CONF_M78_URL) + + athenaConfig.get(Const.CONF_M78_TEXT2SPEECH); + String param = jsonObject.toString(); + log.info("calling:{}, param:{}", apiTextToSpeech, param); + String resp = HttpClient.callHttpServer(apiTextToSpeech, "callM78TextToSpeech", param, false, false, 30); + Result res = GsonUtils.gson.fromJson(resp, new TypeToken>() {}.getType()); + log.info("calling:{}, resCode:{}", apiTextToSpeech, res.getCode()); + return res; + } + + public static Result uploadCodeInfo(String param) { + Map athenaConfig = ResourceUtils.getAthenaConfig(); + String uploadCodeInfo = athenaConfig.get(Const.CONF_M78_URL) + + athenaConfig.get(Const.CONF_M78_UPLOAD_CODE_INFO); + log.info("calling:{}, param:{}", uploadCodeInfo, param); + String resp = HttpClient.callHttpServer(uploadCodeInfo, "uploadCodeInfo", param, false, false, 30); + Result res = GsonUtils.gson.fromJson(resp, new TypeToken>() {}.getType()); + log.info("calling:{}, resCode:{}", uploadCodeInfo, res.getCode()); + return res; + } + + public static void imageHandle(Project project, JsonObject jsonObject) { + String projectName = project.getName(); + WsClient wsClient = new WsClient(); + wsClient.setProjectName(projectName); + String id = UUID.randomUUID().toString(); + wsClient.setId(id); + wsClient.init(getImageHandleConsumer(projectName)); + wsClient.send(jsonObject); + } + + private static Consumer getImageHandleConsumer(String projectName) { + return msg -> { + LocalAiService.sendMsg(msg, projectName); + }; + } +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/PromptService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/PromptService.java new file mode 100644 index 000000000..267d6a019 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/PromptService.java @@ -0,0 +1,1001 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import com.google.common.base.CaseFormat; +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.PsiMethodImpl; +import com.intellij.psi.impl.source.javadoc.PsiDocCommentImpl; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.search.GlobalSearchScope; +import com.unfbx.chatgpt.entity.chat.Message; +import com.xiaomi.youpin.tesla.ip.bo.*; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.Completions; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.Format; +import com.xiaomi.youpin.tesla.ip.bo.robot.AiChatMessage; +import com.xiaomi.youpin.tesla.ip.bo.robot.Role; +import com.xiaomi.youpin.tesla.ip.bo.z.ZKnowledgeRes; +import com.xiaomi.youpin.tesla.ip.common.*; +import com.xiaomi.youpin.tesla.ip.consumer.CodeConsumer; +import com.xiaomi.youpin.tesla.ip.consumer.FinishConsumer; +import com.xiaomi.youpin.tesla.ip.dialog.DialogReq; +import com.xiaomi.youpin.tesla.ip.dialog.DialogResult; +import com.xiaomi.youpin.tesla.ip.dialog.ParamTableDialog; +import com.xiaomi.youpin.tesla.ip.dialog.SelectClassAndMethodDialog; +import com.xiaomi.youpin.tesla.ip.framework.flex.Flex; +import com.xiaomi.youpin.tesla.ip.listener.OpenAiListener; +import com.xiaomi.youpin.tesla.ip.util.*; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import run.mone.openai.Ask; +import run.mone.openai.OpenaiCall; +import run.mone.openai.ReqConfig; +import run.mone.openai.listener.AskListener; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.background.AthenaEditorTask; +import run.mone.ultraman.background.AthenaTask; +import run.mone.ultraman.bo.*; +import run.mone.ultraman.common.CodeUtils; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.common.ImportCode; +import run.mone.ultraman.common.TemplateUtils; +import run.mone.ultraman.manager.InlayHintManager; +import run.mone.ultraman.service.AiCodeService; +import run.mone.ultraman.service.AthenaCodeService; +import run.mone.ultraman.state.AthenaEvent; +import run.mone.ultraman.state.ProjectFsmManager; +import run.mone.ultraman.state.PromptAndFunctionProcessor; + +import java.util.*; +import java.util.stream.Collectors; + +import static com.xiaomi.youpin.tesla.ip.util.PromptUtils.*; + +/** + * @author goodjava@qq.com + * @author baoyu + * @date 2023/5/11 21:53 + *

+ * 这个类主要处理Prompt在Idea中的落地(写入编辑器) + */ +@Slf4j +public class PromptService { + + private static Gson gson = new Gson(); + + /** + * 动态执行 + * + * @param req + * @return + */ + public static String dynamicInvoke(GenerateCodeReq req) { + setReq(req); + switch (req.getPromptType()) { + case createClass -> createClass(req.getProject(), req.getModule().getName(), req.getPromptName()); + case createClass4 -> createClass4(req); + case createMethod -> createMethod(req); + case createMethod2 -> createMethod2(req); + case comment -> addComment(req); + case lineByLineComment -> lineByLineCommentOrCode(req.getPromptName(), req); + case createFile -> createFile(req.getPromptName(), req.getFileName(), req); + case modifyClass -> updateClass(req); + case modifyMethod -> modifyMethod(req); + case select -> select(req, req.getProject(), req.getModule(), req.getPromptInfo()); + case executeBot -> BotService.executeBot(req); + case removeComment -> removeComment(req.getProject()); + case showInfo -> showInfo(req); + case repleaceSelectContent -> repleaceSelectContent(req); + case testPrompt -> testPrompt(req); + case checkPomVersion -> checkPomVersion(req); + case generateBootStrapAnno -> generateAnnoForBootStrap(req.getPromptName(), req.getProject()); + case inlayHint -> inlayHint(req); + case genBizMethodCode -> genBizMethodCode(req); + case generateMethod -> generateMethod(req, req.getProject(), ""); + case bot -> RobotService.bot(req); + case generateTestMethod -> generateTestMethod(req); + case generateMiapiMethod -> generateMiapiMethod(req); + case generateInterface -> generateInterface(req); + case question -> question(req); + case createClass2 -> + createClass2(req.getProject(), req.getPromptName(), req.getShowDialog(), req.getParam()); + default -> { + return "UnSupport"; + } + } + return "ok"; + } + + + private static void createClass4(GenerateCodeReq req) { + String promptName = req.getPromptName(); + List> list = Lists.newArrayList(); + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + String prompt = promptInfo.getData(); + String code = getCode(req, new PromptContext()); + prompt = TemplateUtils.renderTemplate(prompt, ImmutableMap.of("code", code)); + list.add(AiChatMessage.builder().data(prompt).role(Role.user).build()); + List messageList = list.stream().map(it -> com.xiaomi.youpin.tesla.ip.bo.chatgpt.Message.builder().content(it.toString()).role(it.getRole().name()).build()).collect(Collectors.toList()); + Completions completions = Completions.builder() + .stream(false) + .response_format(Format.builder().build()).messages(messageList).build(); + JsonObject jsonObj = AiService.call(GsonUtils.gson.toJson(completions), Long.valueOf(promptInfo.getLabels().getOrDefault("timeout", "50000")), true); + System.out.println(jsonObj); + String className = jsonObj.get("name").getAsString(); + String generateCode = jsonObj.get("code").getAsString(); + String packageStr = jsonObj.get("package").getAsString(); + PsiClassUtils.createClass(req.getProject(), packageStr, className, generateCode); + } + + //ai会向你提问(绝大部分分多步的操作,ai问你更合适) + private static void question(GenerateCodeReq req) { + String projectName = req.getProjectName(); + ProjectFsmManager.map.get(projectName) + .getFsm() + .getEventQueue().add(AthenaEvent.builder() + .promptInfo(req.getPromptInfo()) + .project(req.getProjectName()) + .promptType(req.getPromptType()) + .build()); + } + + //后边代码尽量用这里获取的内容,editor中的内容放入到req中,避免后边的再次获取 + public static void setReq(GenerateCodeReq req) { + ApplicationManager.getApplication().runReadAction(() -> { + Safe.run(() -> { + Project project = req.getProject(); + req.setProjectName(project.getName()); + String moduleName = getModuleName(req); + //当前module的名字 + req.setModuleName(moduleName); + //所有module的列表 + req.setModuleNameList(ProjectUtils.listAllModules(project).stream().filter(it -> !it.equals(project.getName())).collect(Collectors.toList())); + Editor editor = CodeService.getEditor(project); + if (null != editor) { + req.setEditor(editor); + VirtualFile vf = editor.getVirtualFile(); + String fileName = vf.getName(); + req.setFileName(fileName); + PsiClass psiClass = CodeService.getPsiClass(project); + if (null != psiClass) { + req.setQualifiedName(psiClass.getQualifiedName()); + req.setClassPackage(getClassPackage(psiClass.getQualifiedName())); + req.setClassName(psiClass.getName()); + req.setClassCode(psiClass.getText()); + + //这个类的父类或者接口中已经实现的方法定义 + Set methodSet = PsiClassUtils.findInheritedNonPrivateNonStaticMethods(psiClass); + List inheritedMethods = methodSet.stream().map(it -> { + return PsiClassUtils.generateMethodSignature(it); + }).collect(Collectors.toList()); + req.setInheritedMethods(inheritedMethods); + } + PsiMethod psiMethod = CodeService.getMethod(project); + if (null != psiMethod) { + req.setPsiMethod(psiMethod); + req.setMethodCode(psiMethod.getText()); + req.setLineNumberedMethod(CodeService.getMethodAndLineNumbers(psiMethod)); + } + //选中的内容 + req.setSelectText(EditorUtils.getSelectedContentOrLine(editor, false)); + //当前行的内容 + req.setCurrentLine(EditorUtils.getCurrentLineContent(editor)); + Document document = FileDocumentManager.getInstance().getDocument(editor.getVirtualFile()); + if (null != document) { + //这里可能有多个class的内容 + String virtualFileText = document.getText(); + req.setVirtualFileText(virtualFileText); + } + req.setClassCode2(CodeService.getClassText2(project)); + + CaretModel caretModel = editor.getCaretModel(); + if (null != caretModel) { + int offset = caretModel.getOffset(); + req.setOffset(offset); + req.setClassCodeWithMark(replaceCaretWithCode(offset, document)); + } + // 如果是根据注释生成代码,且满足规则,则获取注释 + setCommentInParam(req, editor); + } + req.setSystemName(System.getProperty("os.name")); + req.setIdeaVersion(ApplicationInfo.getInstance().getBuild().asString()); + req.setPluginVersion(new Version().toString()); + }); + }); + } + + private static void setCommentInParam(GenerateCodeReq req, Editor editor){ + if(Action.GENERATE_CODE == ActionUtils.getActionByReq(req)){ + PsiComment comment = EditorUtils.getPsiComment(editor); + if(comment != null && EditorUtils.isCommentInsideClass(comment) + && EditorUtils.isNotClassHeaderComment(comment) + && EditorUtils.isNotMethodComment(comment)){ + Map param = req.getParam(); + if(param == null){ + param = new HashMap<>(); + param.put(Const.GENERATE_CODE_COMMENT, comment.getText().trim()); + req.setParam(param); + }else if (!param.containsKey(Const.GENERATE_CODE_COMMENT)){ + param.put(Const.GENERATE_CODE_COMMENT, comment.getText().trim()); + } + } + } + } + + // 根据传入的carte的位置和psiClass, 将psiClass中caret所在位置替换为"$$这里需要补全代码$$"并返回替换后的代码字符串,不要影响原来的psiClass + public static String replaceCaretWithCode(int caret, Document document) { + if (document == null) { + return ""; + } + String classText = document.getText(); + StringBuilder modifiedText = new StringBuilder(classText); + modifiedText.replace(caret, caret, "$$这里需要补全代码$$"); + return modifiedText.toString(); + } + + private static String getClassPackage(String qualifiedName) { + int lastDotIndex = qualifiedName.lastIndexOf('.'); + if (lastDotIndex >= 0) { + return qualifiedName.substring(0, lastDotIndex); + } + return ""; + } + + + //获取编辑器的注释信息 + private static String getComment(Editor editor) { + return getComment(editor, "//biz:"); + } + + private static String getComment(Editor editor, String str) { + String content = EditorUtils.getSelectContent(editor); + if (content.contains(str)) { + int index = content.indexOf(str) + str.length(); + return content.substring(index); + } + return content; + } + + + /** + * 生成业务方法 + * + * @param req + */ + public static void genBizMethodCode(GenerateCodeReq req) { + Editor editor = CodeService.getEditor(req.getProject()); + if (StringUtils.isEmpty(req.getComment())) { + req.setComment(getComment(editor)); + } + CodeService.moveCaretToEndOfLine(editor); + CodeService.writeCode(req.getProject(), "\n"); + Map m = new HashMap<>(); + m.put("comment", req.getComment()); + //添加代码 + addCode(req, m, new PromptContext()); + //添加上下文 + addContext(req, m, new PromptContext()); + ImportCode importCode = new ImportCode(); + importCode.setProject(req.getProject()); + importCode.setEditor(editor); + + AthenaEditorTask.start(new AthenaEditorTask(req, "Athena:Biz", m, new MessageConsumer() { + @Override + public void onEvent(AiMessage message) { + importCode.append(message.getText()); + } + })); + + } + + private static String addCode(GenerateCodeReq req, Map m, PromptContext context) { + String code = getCode(req, context); + //如果class code 太大,这里需要筛选出需要的method + if (code.length() > AthenaCodeService.CLASS_MAX_LEN && "class".equals(context.getScope())) { + if (StringUtils.isNotEmpty(req.getChatComment())) { + List list = AthenaCodeService.getMethodCodeList(CodeReq.builder().code(code).requirement(req.getChatComment()).build()); + if (list.size() > 0) { + code = list.stream().collect(Collectors.joining("\n")); + } + } + } + m.put("code", code); + if (StringUtils.isNotEmpty(req.getMethodCode())) { + m.put("methodCode", req.getMethodCode()); + } + return code; + } + + + //添加上下文信息到映射中 + public static void addContext(GenerateCodeReq req, Map m, PromptContext promptContext) { + Mutable context = new MutableObject<>(); + String scope = req.getScope(); + if (!StringUtils.isEmpty(scope)) { + promptContext.setScope(scope); + //method不需要计算任何上下文 + if (scope.equals("method")) { + promptContext.setScope("method"); + m.put("context", ""); + return; + } + } + //可以粗略的认为是把@Resource的类导入到上下文 + processGenerateCodeReq(req, promptContext, context); + m.put("context", context.getValue()); + } + + private static void processGenerateCodeReq(GenerateCodeReq req, PromptContext promptContext, Mutable context) { + if (LabelUtils.isOpen(req.getProject(), req.getPromptInfo(), "context")) { + ApplicationManager.getApplication().runReadAction(() -> { + PsiClass clazz = CodeService.getPsiClass(req.getProject()); + if (null == clazz) { + return; + } + List list = PsiClassUtils.findFieldsWithResourceAnnotation(clazz); + if (LabelUtils.isOpen(req.getProject(), req.getPromptInfo(), "ai_context")) { + List resourceCode = list.stream().map(it -> it.getType().getCanonicalText()).toList(); + promptContext.setResourceCode(resourceCode); + //设置po列表信息 + setPoList(promptContext, list); + } else { + List classList = PsiClassUtils.getClassText(req.getProject(), list); + context.setValue(Joiner.on("\n").join(classList)); + } + + //用Service那种模式的Flex + setPoClassInfo(promptContext, clazz); + }); + } + } + + private static void setPoClassInfo(PromptContext promptContext, PsiClass clazz) { + String boCode = Flex.findAndProcessServiceImplWithGeneric(clazz); + if (StringUtils.isNotEmpty(boCode)) { + List polist = promptContext.getPoClassInfos(); + if (null == polist) { + polist = Lists.newArrayList(PoClassInfo.builder().code(boCode).name("").build()); + } else { + polist.add(PoClassInfo.builder().code(boCode).name("").build()); + } + promptContext.setPoClassInfos(polist); + } + } + + private static void setPoList(PromptContext promptContext, List list) { + Map map = Maps.newHashMap(); + list.stream().forEach(it -> { + if (it.getType() instanceof PsiClassType pct) { + PsiClass psiClass = pct.resolve(); + Pair pair = Flex.getBaseMapperGenericTypeNameAndText(psiClass); + if (StringUtils.isNotEmpty(pair.getKey())) { + map.put(pair.getKey(), pair.getValue()); + } + } + }); + promptContext.setPoClassInfos(map.entrySet().stream().map(it -> { + return PoClassInfo.builder().name(it.getKey()).code(it.getValue()).build(); + }).collect(Collectors.toList())); + } + + public static String getResourceFromAi(Project project, Map m, PromptContext promptContext, List resourceCode) { + List resouceList = new ArrayList<>(); + if (resourceCode.size() > 3 && AthenaContext.ins().gptModel().isOptimizeTokens()) { + // 用chatGpt分析一遍需要用到哪些resource下的内容 + Map resourceMap = new HashMap<>(); + resourceMap.put("beanList", gson.toJson(resourceCode)); + String comment = ""; + if (m.get("comment") == null) { + comment = m.get("code"); + } + resourceMap.put("comment", comment); + String res = CodeService.call("ai_context", resourceMap); + + if (StringUtils.isEmpty(res)) { + return ""; + } + List tmpList = gson.fromJson(res, new TypeToken>() { + }.getType()); + resouceList.addAll(tmpList); + } else { + resouceList.addAll(resourceCode); + } + + //如果resource里边已经有了,则module context就不需要再次引入了 + promptContext.setResourceBeanList(resouceList); + + return ApplicationManager.getApplication().runReadAction((Computable) () -> { + String context = resouceList.stream().map(it -> { + String str = PsiClassUtils.getClassText(project, it); + return str; + }).collect(Collectors.joining("\n")); + return context; + }); + } + + + public static void inlayHint(GenerateCodeReq req) { + req.setFormat(false); + CodeService.insertCode(req.getProject(), "", false); + PromptInfo promptInfo = Prompt.getPromptInfo("hi2"); + PromptType promptType = Prompt.getPromptType(promptInfo); + Map m = new HashMap<>(); + Editor editor = CodeService.getEditor(req.getProject()); + //添加代码 + addCode(req, m, new PromptContext()); + //添加上下文 + addContext(req, m, new PromptContext()); + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + + AthenaEditorTask.start(new AthenaEditorTask(req, "Athena", m, new FinishConsumer() { + + @Override + public void end(AiMessage message) { + String content = getContent(); + ApplicationManager.getApplication().invokeLater(() -> { + String newLines = "\n".repeat(content.split("\n").length); + WriteCommandAction.runWriteCommandAction(req.getProject(), () -> { + editor.getDocument().insertString(offset, newLines); + PsiDocumentManager.getInstance(req.getProject()).commitDocument(editor.getDocument()); + }); + InlayHintManager.ins().addInlayHint(editor, offset, content); + }); + } + })); + } + + /** + * 测试prompt的接口 + * + * @param req + */ + public static void testPrompt(GenerateCodeReq req) { + //从aiproxy获取参数列表 + Map map = getParamsFromAiProxy(req.getPromptName(), req.getPromptInfo().getMeta()); + //输入prompt参数 + ParamTableDialog table = new ParamTableDialog(ParamDialogReq.builder().title("test prompt").build(), req.getProject(), map, ImmutableMap.of(), req.getPromptInfo()); + table.setConsumer(values -> { + Editor editor = EditorUtils.getOrOpenEditor(req.getProject(), "prompt.md", ""); + Map m = table.getValuesMap().entrySet().stream().collect(Collectors.toMap(it -> it.getKey(), it -> it.getValue().toString())); + AthenaEditorTask.start(new AthenaEditorTask(req, "Athena", m, new CodeConsumer(editor, req))); + }); + table.show(); + } + + private static void repleaceSelectContent(GenerateCodeReq req) { + Editor editor = CodeService.getEditor(req.getProject()); + if (null == editor) { + HintUtils.show(req.getProjectName(), com.xiaomi.youpin.tesla.ip.bo.Message.selectTextMsg, true); + return; + } + String text = getCode(req, new PromptContext()); + if (StringUtils.isNotEmpty(text)) { + SelectionModel selectionModel = editor.getSelectionModel(); + if (selectionModel.hasSelection()) { + int start = selectionModel.getSelectionStart(); + int end = selectionModel.getSelectionEnd(); + Document document = CodeService.getDocument(req.getProject()); + AthenaEditorTask task = new AthenaEditorTask(req, "Athena", ImmutableMap.of("code", text), new MessageConsumer() { + private StringBuilder sb = new StringBuilder(); + + @Override + public void onEvent(AiMessage message) { + sb.append(message.getText()); + } + + @Override + public void end(AiMessage message) { + WriteCommandAction.runWriteCommandAction(req.getProject(), () -> { + document.replaceString(start, end, sb.toString()); + PsiDocumentManager.getInstance(req.getProject()).commitDocument(document); + }); + } + }); + AthenaEditorTask.start(task); + } + } + } + + @NotNull + private static String getModuleName(GenerateCodeReq req) { + String moduleName = ""; + if (null == req.getModule()) { + Module module = ProjectUtils.getCurrentModule(req.getProject()); + if (null != module) { + req.setModule(module); + moduleName = module.getName(); + } + } else { + moduleName = req.getModule().getName(); + } + return moduleName; + } + + /** + * 在聊天窗口显示信息 + * + * @param req + */ + public static void showInfo(GenerateCodeReq req) { + //不需要格式化代码 + req.setFormat(false); + //在聊天框显示 + req.setTaskType("chat"); + generateMethod(req); + } + + + public static void generateMethod(Project project, String content) { + ClientData clientData = AthenaContext.ins().getClientData(project.getName()); + GenerateCodeReq req = AiCodeService.getGenerateCodeReq(project, clientData.getScope(), content); + req.setEditor(CodeService.getEditor(project)); + req.setModule(ProjectUtils.getCurrentModule(project)); + req.setTaskType("edit"); + PromptService.setReq(req); + PromptService.generateMethod(req); + //添加到聊天框 + ChromeUtils.call(req.getProject().getName(), content, 0); + } + + + public static void generateMethod(GenerateCodeReq req) { + generateMethod(req, true); + } + + + //创建方法都收口在这里了 + public static AthenaTask generateMethod(GenerateCodeReq req, boolean startTask) { + Project project = req.getProject(); + String promptName = req.getPromptName(); + Map aiReqMap = new HashMap<>(); + initAiReqMap(req, aiReqMap); + //如果是chat,这里拿到的会是注释 + PromptContext context = new PromptContext(); + context.setProject(project.getName()); + context.setModule(req.getModule().getName()); + context.setEditor(req.getEditor()); + String code = addCode(req, aiReqMap, context); + + if (StringUtils.isEmpty(code) && req.getPromptInfo().open("needCode")) { + log.info("code is empty prompt name:{}", promptName); + return null; + } + + AthenaTask task = new AthenaTask(project, "Athena", promptName, code, aiReqMap); + //在这里的都是异步执行 + task.setInitRunnable(() -> { + if (StringUtils.isNotEmpty(req.getUserSettingScope())) { + req.setScope(req.getUserSettingScope()); + } else { + //自动分析scope + if (req.getPromptInfo().open("analysis_scope") && AthenaContext.ins().gptModel().isSupportJsonResponse()) { + analysisScope(req, context); + } else { + req.setScope("class"); + } + } + addContext(req, aiReqMap, context); + addClass(req, aiReqMap, context); + addField(req, aiReqMap); + addInheritedMethods(req, aiReqMap, context); + }); + + task.setReq(req); + task.setFormat(req.isFormat()); + task.setPromptContext(context); + task.setType(req.getTaskType()); + if (startTask) { + AthenaTask.start(task); + } + return task; + } + + //添加抽象类或interface中已经实现的方法定义 + public static void addInheritedMethods(GenerateCodeReq req, Map aiReqMap, PromptContext context) { + if (null == req.getInheritedMethods()) { +// NotificationCenter.notice(ErrorMessage.ERR_NOT_IN_CLASS_SCOPE, NotificationType.ERROR); +// throw new RuntimeException(ErrorMessage.ERR_NOT_IN_CLASS_SCOPE); + log.error(ErrorMessage.ERR_NOT_IN_CLASS_SCOPE); + } else { + aiReqMap.put("inheritedMethods", req.getInheritedMethods().stream().collect(Collectors.joining("\n\n\n"))); + } + } + + private static void initAiReqMap(GenerateCodeReq req, Map aiReqMap) { + aiReqMap.put("current_module_name", req.getModuleName()); + aiReqMap.put("project_module_list", req.getModuleNameList().stream().collect(Collectors.joining(","))); + } + + public static void analysisScope(GenerateCodeReq req, PromptContext context) { + Map m = new HashMap<>(); + m.put("class", req.getClassCode()); + //获取方法签名(代码补全的时候) + if (LabelUtils.isOpen(req.getProject(), req.getPromptInfo(), "method_info")) { + m.put("code", req.getMethodCode()); + } else { + //获取注释 + String comment = req.getParam().getOrDefault(Const.GENERATE_CODE_COMMENT, req.getChatComment()); + if (StringUtils.isEmpty(comment)) { + comment = req.getCurrentLine(); + } + if (StringUtils.isEmpty(comment)) { + context.setScope("class"); + req.setScope("class"); + return; + } + m.put("code", comment); + String scope = com.xiaomi.youpin.tesla.ip.common.StringUtils.extractEndingKeyword(comment); + //不再计算scope + if (StringUtils.isNotEmpty(scope)) { + context.setScope(scope); + req.setScope(scope); + return; + } + } + initAiReqMap(req, m); + PromptInfo promptInfo = Prompt.getPromptInfo("analysis_scope"); + JsonObject obj = PromptAndFunctionProcessor.callPrompt(req.getProject(), promptInfo, m); + String scope = obj.get("scope").getAsString(); + context.setScope(scope); + req.setScope(scope); + } + + //计算两数和 + + public static void addField(GenerateCodeReq req, Map map) { + if (LabelUtils.isOpen(req.getProject(), req.getPromptInfo(), "select_field")) { + map.put("field", CodeService.getPsiField(req.getProject()).getName()); + } + } + + public static void addClass(GenerateCodeReq req, Map map, PromptContext context) { + map.put("lang", "java"); // HINT: 标记来源 + if (LabelUtils.isOpen(req.getProject(), req.getPromptInfo(), "add_class") && !"method".equals(context.getScope())) { + List list = AthenaCodeService.parseMethodCode(req.getClassCode()); + List fieldList = AthenaCodeService.parseFieldCode(req.getClassCode()); + //通过需求生成的代码,class不能用全部的,不然会超过预期 + if (StringUtils.isNotEmpty(context.getComment())) { + //后边异步计算 + context.setMethodCodeList(list); + context.setFieldCodeList(fieldList); + context.setClazzName(req.getClassName()); // HINT: class如果使用FQCN则不能被parse + } + + //完成脱敏 + String classCode = AiCodeService.desensitizeCode(req.getClassCode()); + log.info("desensitize code class:{}", classCode); + map.put("class", classCode); + map.put("fqcn", req.getQualifiedName()); //HINT: FQCN单独传递, 在prompt模板中需要使用自定义函数 ${prompt_value('fqcn','')}来实现向下兼容 + } else { + map.put("class", ""); + } + } + + + public static String getCode(GenerateCodeReq req, PromptContext context) { + String text = ""; + if (req.getPromptInfo().open("selectComment")) { + text = req.getChatComment(); + context.setComment(text); + } + if (req.getPromptInfo().open("selectText")) { + text = req.getSelectText(); + if (StringUtils.isEmpty(text)) { + HintUtils.show(req.getEditor(), com.xiaomi.youpin.tesla.ip.bo.Message.selectTextMsg, true); + } + } + if (req.getPromptInfo().open("selectMethod")) { + context.setScope("method"); + text = req.getMethodCode(); + if (StringUtils.isEmpty(text)) { + HintUtils.show(req.getEditor(), com.xiaomi.youpin.tesla.ip.bo.Message.selectMethodMsg, true); + } + } + if (req.getPromptInfo().open("selectClass")) { + context.setScope("class"); + context.setProject(req.getProject().getName()); + context.setModule(!Objects.isNull(req.getModule()) ? req.getModule().getName() : ProjectUtils.getCurrentModule(req.getProject()).getName()); + text = req.getClassCode(); + } + + //选择整个java文件(里边有package信息) + if (req.getPromptInfo().open("selectFile")) { + text = req.getVirtualFileText(); + } + + if (req.getPromptInfo().open("selectClassName")) { + text = req.getQualifiedName(); + } + + if (req.getPromptInfo().open("commitFile")) { + text = GitUtils.getAffectedFileNames(req.getProject()).stream().collect(Collectors.joining("\n")); + } + + if (req.getPromptInfo().open("selectClass2")) { + text = req.getClassCode2(); + } + return text == null ? "" : text; + } + + /** + * 删除逐行注释 + * + * @param project + */ + private static void removeComment(Project project) { + PsiMethod psiMethod = CodeService.getMethod(project); + Editor editor = CodeService.getEditor(project); + if (null == psiMethod) { + HintUtils.show(editor, com.xiaomi.youpin.tesla.ip.bo.Message.selectMethodMsg, true); + return; + } + PsiMethodUtils.deleteCommentsFromMethod(project, psiMethod, comment -> comment.getText().startsWith("//Athena:")); + } + + /** + * 生成方法(在edit中) + * + * @param project + * @param text + */ + public static void generateMethod(GenerateCodeReq req, Project project, String text) { + Editor codeEditor = CodeService.getEditor(project); + if (StringUtils.isEmpty(text)) { + text = getComment(codeEditor, "//ai:"); + } + CodeService.moveCaretToEndOfLine(codeEditor); + CodeService.writeCode2(project, codeEditor, "\n"); + + req.setChatComment(text); + generateMethod(req); + } + + + private static void createMethod(GenerateCodeReq req) { + Project project = req.getProject(); + Editor editor = CodeService.getEditor(project); + CodeService.writeCode2(project, editor, "\n"); + CodeService.generateCodeWithAi2(project, req.getPromptName(), new String[]{req.getMeta()}, (p, code) -> CodeService.writeCode2(p, editor, code)); + } + + /** + * 创建方法2 + *

+ * 会打开两个表单 + * 1.填参数 + * 2.选中类和方法 + * + *

+ * 选择类和方法,然后插入代码 + *

+ * 可以用来生成Controller中的方法 + * + * @param req + */ + public static void createMethod2(GenerateCodeReq req) { + String promptName = req.getPromptName(); + Project project = req.getProject(); + PsiMethod pm = CodeService.getMethod(req.getProject()); + //没有选中方法(目前创建方法是根据某个已经选中的方法) + if (null == pm) { + HintUtils.show(CodeService.getEditor(req.getProject()), com.xiaomi.youpin.tesla.ip.bo.Message.selectMethodMsg, true); + return; + } + + String mn = pm.getName(); + + String methodCode = pm.getText(); + PsiClass pc = CodeService.getPsiClass(req.getProject()); + + String serviceName = pc.getQualifiedName(); + String shortServiceName = pc.getNameIdentifier().getText(); + + //选择类的label + String cmd = req.getPromptInfo().getLabels().get("cmd"); + String type = req.getPromptInfo().getLabels().get("type"); + String name = req.getPromptInfo().getLabels().get("name"); + + //获取需要填写那些参数 + Map map = getParamsFromAiProxy(promptName, req.getPromptInfo().getMeta()); + + setLabels(req, map); + map.put("methodName", mn); + map.put("serviceName", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, shortServiceName)); + + String reqPackage = LabelUtils.getLabelValue(req.getProject(), req.getPromptInfo(), Const.REQ_PACKAGE, Const.DEFAULT_REQ_PACKAGE); + List list = PackageUtils.getClassList(req.getProject(), reqPackage); + + ParamTableDialog table = new ParamTableDialog(ParamDialogReq.builder().title("param").build(), project, map, new HashMap<>(), req.getPromptInfo()); + table.setConsumer(cp -> { + Map m = table.getValuesMap(); + String reqClass = m.getOrDefault("reqClass", "").toString(); + + //用来获取要添加代码的Class和Method + Module module = req.getModule(); + SelectClassAndMethodDialog dialog = new SelectClassAndMethodDialog(project, DialogReq.builder().cmd(cmd).type(type).name(name).module(module).build()); + dialog.show(); + int exitCode = dialog.getExitCode(); + if (exitCode != DialogWrapper.OK_EXIT_CODE) { + return; + } + + DialogResult result = dialog.getResult(); + String methodName = result.getData().get("method"); + String className = result.getData().get("class"); + + + StringBuilder sb = new StringBuilder(); + + //打开PsiClass(需要更新的) + PsiClass psiClass = CodeService.openJavaClass(project, className); + Editor editor = CodeService.getEditor(req.getProject()); + //添加import + addImports(req, project, serviceName, reqClass, editor); + //添加字段 + addFields(project, serviceName, shortServiceName, psiClass, editor); + + //移动到合理的位置 + if (methodName.equals("New")) { + EditorUtils.moveToLastMethodEnd(psiClass, editor); + CodeService.writeCode2(project, editor, "\n"); + } else { + PsiMethod psiMethod = CodeService.getMethod(psiClass, methodName); + CodeService.deleteMethod(project, psiMethod); + } + + sb.append(req.getMeta()).append("\n"); + sb.append(methodCode).append("\n"); + String param = sb.toString(); + + Map params = Maps.newHashMap(); + m.put("code", param); + m.put("service", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, shortServiceName)); + m.put("reqClass", JavaClassUtils.getClassName(reqClass)); + + //修改Req(添加入字段) + modifyReq(req, pm, reqClass); + + //interface中添加方法(Dubbo中的interface需要同步更新) + addMethodToInterface(req, psiClass, pm, PsiClassUtils.findClassByName(req.getProject(), reqClass)); + + m.entrySet().forEach(entry -> params.put(entry.getKey(), entry.getValue().toString())); + + //生成方法代码 + CodeService.generateCodeWithAi3(req.getProject(), promptName, new String[]{}, params, (p, code) -> CodeService.writeCode2(p, editor, code)); + }); + table.show(); + + + } + + public static void addFields(Project project, String serviceName, String shortServiceName, PsiClass psiClass, Editor editor) { + CodeService.addField(project, editor.getDocument(), psiClass, String.format("@Resource\nprivate %s %s;", shortServiceName, CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, shortServiceName)), serviceName); + } + + public static void addImports(GenerateCodeReq req, Project project, String serviceName, String reqClass, Editor editor) { + addImports(req, project, serviceName, reqClass, editor, false, false, ""); + } + + public static void addImports(GenerateCodeReq req, Project project, String serviceName, String reqClass, Editor editor, boolean unitTest, boolean resource, String unitVersion) { + ArrayList importService = Lists.newArrayList(); + importService.add(serviceName); + if (null != reqClass) { + importService.add(reqClass); + } + importService.addAll(PromptUtils.getImportList(req.getPromptInfo())); + if (unitTest) { + importService.addAll(TestUtils.getImportList(unitVersion)); + } + if (resource) { + importService.addAll(ProjectUtils.getResourceImport(project)); + } + CodeService.addImport(project, editor, importService); + } + + /** + * 给interface中添加方法(返回值可能被包装要注意) + * + * @param psiClass + */ + private static void addMethodToInterface(GenerateCodeReq req, PsiClass psiClass, PsiMethod pm, PsiClass reqClass) { + boolean modifyReq = Boolean.valueOf(req.getPromptInfo().getLabels().getOrDefault("add_interface_method", "false")); + if (!modifyReq) { + return; + } + Safe.run(() -> { + Project project = req.getProject(); + PsiClass interfacePsiClass = PsiClassUtils.getInterface(psiClass); + PsiType type = PsiElementFactory.getInstance(project).createType(reqClass); + PsiType returnType = getReturnType(req, project, pm, interfacePsiClass); + List list = Lists.newArrayList(ParamInfo.builder().name(reqClass.getName()).psiType(type).build()); + WriteCommandAction.runWriteCommandAction(project, () -> PsiClassUtils.addMethod(project, interfacePsiClass, AddMethodConfig.builder().name(pm.getName()).returnType(returnType).isInterface(true).build(), list)); + }); + } + + + public static PsiType getReturnType(GenerateCodeReq req, Project project, PsiMethod psiMethod, PsiClass psiClass) { + PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); + String returnType = req.getPromptInfo().getLabels().getOrDefault("return_type", ""); + if (org.apache.commons.lang3.StringUtils.isNotEmpty(returnType)) { + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiClassUtils.addImport(psiClass, returnType); + }); + PsiClass resultClass = JavaPsiFacade.getInstance(project).findClass("com.xiaomi.youpin.infra.rpc.Result", GlobalSearchScope.allScope(project)); + @Nullable PsiType rt = psiMethod.getReturnType(); + if (rt instanceof PsiPrimitiveType) { + PsiPrimitiveType primitiveType = (PsiPrimitiveType) rt; + rt = primitiveType.getBoxedType(PsiManager.getInstance(project), GlobalSearchScope.allScope(project)); + } + PsiType[] typeArguments = {rt}; + PsiType psiType = factory.createType(resultClass, typeArguments); + return psiType; + } else { + return psiMethod.getReturnType(); + } + } + + + private static void modifyReq(GenerateCodeReq req, PsiMethod pm, String reqClass) { + //修改Req里边的参数 + boolean modifyReq = Boolean.valueOf(req.getPromptInfo().getLabels().getOrDefault("modify_req", "false")); + if (modifyReq) { + Safe.run(() -> { + List list = PsiMethodUtils.getParamInfoList(pm); + PsiClass reqPsiClass = PsiClassUtils.findClassByName(req.getProject(), reqClass); + WriteCommandAction.runWriteCommandAction(req.getProject(), () -> list.stream().forEach(it -> PsiClassUtils.addField(req.getProject(), reqPsiClass, it.getName(), it.getPsiType()))); + }); + } + } + + private static void setLabels(GenerateCodeReq req, Map map) { + Map labels = req.getPromptInfo().getLabels(); + if (null != labels) { + labels.entrySet().forEach(entry -> { + if (map.keySet().contains(entry.getKey())) { + map.put(entry.getKey(), entry.getValue()); + } + }); + } + } + + //暂时只生成接口引入 + public static void generateMiapiMethod(GenerateCodeReq req) { + Project project = req.getProject(); + Editor editor = req.getEditor(); + String requirement = getCode(req, new PromptContext()).replace("//", ""); + List list = AthenaCodeService.getCodeList(CodeReq.builder().requirement(requirement).fileTypeList(Arrays.asList("miapi")).build()); + if (CollectionUtils.isNotEmpty(list)) { + list.forEach(i -> { + log.info("miapi similarQuery rst:" + i.getContent()); + CodeService.writeCode2(project, editor, "\n"); + CodeService.generateCodeWithAi3(project, req.getPromptName(), new String[]{i.getContent()}, ImmutableMap.of("interfaceInfo", i.getContent()), (p, code) -> CodeService.writeCode2(p, editor, code)); + }); + } + } + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ProxyAiService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ProxyAiService.java new file mode 100644 index 000000000..a7835b1bf --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ProxyAiService.java @@ -0,0 +1,100 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.intellij.notification.NotificationType; +import com.xiaomi.youpin.tesla.ip.bo.ProxyAsk; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.Completions; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.Message; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.NotificationCenter; +import lombok.extern.slf4j.Slf4j; +import okhttp3.*; +import org.apache.commons.lang3.StringUtils; +import run.mone.ultraman.AthenaContext; + +import java.nio.charset.Charset; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * @author goodjava@qq.com + * @date 2023/12/5 22:13 + */ +@Slf4j +public class ProxyAiService { + + + private static Gson gson = new Gson(); + + public static JsonObject call(List messageList) { + return call(messageList, 50000); + } + + public static JsonObject call(String r, long time, boolean vip, boolean jsonResult) { + ProxyAsk pa = new ProxyAsk(); + if (StringUtils.isNotEmpty(AthenaContext.ins().getGptModel())) { + pa.setModel(AthenaContext.ins().getGptModel()); + } + pa.setZzToken(ConfigUtils.getConfig().getzToken()); + pa.setParams(new String[]{r}); + String req = gson.toJson(pa); + return call0(req, time, vip, jsonResult); + } + + //调用ai proxy (调用的是json接口,返回的数据一定是json格式) + public static JsonObject call0(String req, long time, boolean vip, boolean jsonResult) { + OkHttpClient client = new OkHttpClient.Builder() + .connectTimeout(time, TimeUnit.MILLISECONDS) + .readTimeout(time, TimeUnit.MILLISECONDS) + .build(); + + String action = vip ? "/json" : "/json2"; + for (int i = 0; i < 3; i++) { + log.info("proxy ai call begin req:{} time:{}", req, i + 1); + MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); + Request request = new Request.Builder() + .url(ConfigUtils.getConfig().getAiProxy() + action) + .post(RequestBody.create(mediaType, req.getBytes(Charset.forName("utf8")))) + .build(); + + try (Response response = client.newCall(request).execute()) { + // 判断请求是否成功 + if (response.isSuccessful() && response.body() != null) { + String responseBody = response.body().string(); + log.info("proxy ai call finish res:{}", responseBody); + + if (jsonResult) { + JsonObject jsonObject = gson.fromJson(responseBody, JsonObject.class); + if (null != jsonObject.get("authCode")) { + NotificationCenter.notice("call ai error," + jsonObject.get("msg").getAsString(), NotificationType.ERROR); + return null; + } + return jsonObject; + } + JsonObject res = new JsonObject(); + res.addProperty("data", responseBody); + return res; + } else { + log.info("proxy ai call failure code:{}", response.code()); + } + } catch (Throwable e) { + log.info("proxy ai call error:{}", e.getMessage()); + e.printStackTrace(); + } + } + return null; + } + + public static JsonObject call(List messageList, long time) { + Completions completions = Completions.builder().messages(messageList).build(); + ProxyAsk pa = new ProxyAsk(); + if (StringUtils.isNotEmpty(AthenaContext.ins().getGptModel())) { + pa.setModel(AthenaContext.ins().getGptModel()); + } + pa.setParams(new String[]{gson.toJson(completions)}); + String req = gson.toJson(pa); + return call0(req, time, true, true); + } + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/PsiMethodUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/PsiMethodUtils.java new file mode 100644 index 000000000..39fdbeee2 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/PsiMethodUtils.java @@ -0,0 +1,176 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import com.google.gson.JsonObject; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.RefactoringFactory; +import com.intellij.refactoring.RenameRefactoring; +import com.intellij.util.IncorrectOperationException; +import com.xiaomi.youpin.tesla.ip.bo.ParamInfo; +import org.jetbrains.annotations.NotNull; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/6/3 22:31 + */ +public class PsiMethodUtils { + + + /** + * 删除指定方法中的注释 + * + * @param psiMethod + */ + public static void deleteCommentsFromMethod(Project project, PsiMethod psiMethod, Predicate predicate) { + @NotNull Collection comments = PsiTreeUtil.collectElementsOfType(psiMethod, PsiComment.class); + WriteCommandAction.runWriteCommandAction(project, () -> { + for (PsiComment comment : comments) { + if (predicate.test(comment)) { + comment.delete(); + } + } + }); + } + + public static List getParamInfoList(PsiMethod psiMethod) { + return Arrays.stream(psiMethod.getParameterList().getParameters()).map(it -> { + String name = it.getName(); + String type = it.getType().getCanonicalText(); + return ParamInfo.builder().name(name).type(type).psiType(it.getType()).build(); + }).collect(Collectors.toList()); + } + + + /** + * 修改方法名 + * + * @param project 项目对象 + * @param document 文档对象 + * @param method 方法对象 + * @param newName 新方法名 + */ + public static void modifyMethodName(Project project, Document document, PsiMethod method, String newName) { + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiIdentifier identifier = method.getNameIdentifier(); + int startOffset = identifier.getTextRange().getStartOffset(); + int endOffset = identifier.getTextRange().getEndOffset(); + document.replaceString(startOffset, endOffset, newName); + PsiDocumentManager.getInstance(project).commitDocument(document); + }); + } + + + /** + * Renames the specified method within the given project to the new name using a rename refactoring process wrapped in a write command action. + */ + public static void renameMethod(Project project, PsiMethod method, String newName) { + ApplicationManager.getApplication().invokeLater(() -> { + RenameRefactoring renameRefactoring = RefactoringFactory.getInstance(project) + .createRename(method, newName); + renameRefactoring.setSearchInComments(false); + renameRefactoring.setSearchInNonJavaFiles(false); + renameRefactoring.run(); + }); + } + + //replace PsiMethod整体的信息,参数是一个String method code(class) + public static void replacePsiMethod(Project project, PsiMethod psiMethod, String methodCode) { + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); + PsiMethod newMethod = elementFactory.createMethodFromText(methodCode.trim(), psiMethod.getContainingFile()); + psiMethod.replace(newMethod); + }); + } + + + /** + * 在指定项目中重命名给定的参数。 + * + * @param project 当前工作的项目对象。 + * @param parameter 要重命名的参数。 + * @param newName 参数的新名称。 + */ + public static void renameParameter(Project project, PsiParameter parameter, String newName) { + ApplicationManager.getApplication().invokeLater(() -> { + // 确保我们在写操作允许的上下文中执行重命名 + CommandProcessor.getInstance().executeCommand(project, () -> { + try { + // 使用重构 API 创建一个重命名重构动作 + RenameRefactoring renameRefactoring = RefactoringFactory.getInstance(project) + .createRename(parameter, newName); + renameRefactoring.setSearchInComments(false); + renameRefactoring.setSearchInNonJavaFiles(false); + renameRefactoring.run(); + } catch (IncorrectOperationException e) { + // 处理可能的异常 + } + }, "Rename Parameter", null); + }); + } + + // 通过getFirstChild迭代,获取PsiMethod的第一叶子节点 + public static PsiElement getFirstLeafNode(PsiMethod psiMethod) { + PsiElement element = psiMethod.getFirstChild(); + while (element != null && element.getFirstChild() != null) { + element = element.getFirstChild(); + } + return element; + } + + + public static JsonObject extractMethodCallParts(@NotNull Project project, @NotNull Editor editor) { + JsonObject res = new JsonObject(); + // 获取当前 PsiFile + PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project); + PsiFile psiFile = psiDocumentManager.getPsiFile(editor.getDocument()); + if (psiFile == null) return res; + + // 获取当前光标位置的 PsiElement + int offset = editor.getCaretModel().getOffset(); + PsiElement elementAtCursor = psiFile.findElementAt(offset); + if (elementAtCursor == null) return res; + + // 向上遍历 PSI 树,直到找到方法调用表达式 + PsiElement parent = PsiTreeUtil.getParentOfType(elementAtCursor, PsiMethodCallExpression.class); + if (parent instanceof PsiMethodCallExpression) { + PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) parent; + + // 获取方法名 + PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); + String methodName = methodExpression.getReferenceName(); + System.out.println("Method name: " + methodName); + + String methodCode = methodExpression.resolve().getText(); + res.addProperty("methodCode", methodCode); + res.addProperty("methodName", methodName); + + + // 获取调用对象 + PsiExpression qualifier = methodExpression.getQualifierExpression(); + if (qualifier instanceof PsiReferenceExpression) { + PsiReferenceExpression referenceExpression = (PsiReferenceExpression) qualifier; + PsiElement resolved = referenceExpression.resolve(); + if (resolved instanceof PsiVariable) { + System.out.println("Referenced variable: " + ((PsiVariable) resolved).getName()); + PsiVariable pv = (PsiVariable) resolved; + res.addProperty("className", pv.getType().getCanonicalText()); + } + } + } + return res; + } + + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/QuickFixInvokeUtil.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/QuickFixInvokeUtil.java new file mode 100644 index 000000000..60863281c --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/QuickFixInvokeUtil.java @@ -0,0 +1,210 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.daemon.impl.ShowIntentionsPass; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInspection.*; +import com.intellij.codeInspection.ex.InspectionProfileImpl; +import com.intellij.codeInspection.ex.InspectionToolWrapper; +import com.intellij.codeInspection.ex.LocalInspectionToolWrapper; +import com.intellij.codeInspection.ex.Tools; +import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.TextEditor; +import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.intellij.profile.codeInspection.InspectionProjectProfileManager; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiFile; +import com.intellij.util.IncorrectOperationException; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author HawickMason@xiaomi.com + * @aythor goodjava@qq.com + * @date 4/18/24 15:00 + */ +@Slf4j +public class QuickFixInvokeUtil { + + @Deprecated + public static void applyQuickFixes(@NotNull Project project, @NotNull PsiFile file) { + InspectionManager inspectionManager = InspectionManager.getInstance(project); + InspectionProfileImpl inspectionProfile = InspectionProjectProfileManager.getInstance(project).getCurrentProfile(); + + // 获取所有启用的检查工具 + List inspectionTools = inspectionProfile.getAllEnabledInspectionTools(project); + + for (Tools toolWrapper : inspectionTools) { + if (toolWrapper instanceof LocalInspectionToolWrapper) { + LocalInspectionTool localInspectionTool = ((LocalInspectionToolWrapper) toolWrapper).getTool(); + ProblemsHolder problemsHolder = new ProblemsHolder(inspectionManager, file, false); + PsiElementVisitor visitor = localInspectionTool.buildVisitor(problemsHolder, true); + file.accept(visitor); + + List problems = problemsHolder.getResults(); + for (ProblemDescriptor problem : problems) { + // 获取问题描述符的 Quick Fixes + QuickFix[] fixes = problem.getFixes(); + if (fixes != null) { + for (QuickFix fix : fixes) { + // 应用第一个可用的 Quick Fix + applyQuickFix(project, problem, fix); + break; // 只应用一个 Quick Fix,如果需要应用多个,移除这个 break + } + } + } + } + } + } + + public static List problems(@NotNull Project project, @NotNull PsiFile file, PsiClass pc) { + InspectionManager inspectionManager = InspectionManager.getInstance(project); + InspectionProfileImpl inspectionProfile = InspectionProjectProfileManager.getInstance(project).getCurrentProfile(); + // 获取所有启用的检查工具 + List inspectionTools = inspectionProfile.getAllEnabledInspectionTools(project); + List res = new ArrayList<>(); + + + Task.Backgroundable task = new Task.Backgroundable(project, "Running Task", true) { + public void run(@NotNull ProgressIndicator indicator) { + // 设置进度指示器的初始文本 + indicator.setText("Running task..."); + + for (Tools toolWrapper : inspectionTools) { + InspectionToolWrapper t = toolWrapper.getTool(); + InspectionProfileEntry e = t.getTool(); + if (e instanceof LocalInspectionTool lt) { + res.addAll(lt.processFile(file,inspectionManager)); + } + } + + System.out.println(res); + + } + }; + + ProgressManager.getInstance().run(task); + + return res; + + } + + private static void applyQuickFix(@NotNull Project project, @NotNull ProblemDescriptor problem, @NotNull QuickFix quickFix) { + // 在写操作中应用 Quick Fix + WriteCommandAction.runWriteCommandAction(project, () -> quickFix.applyFix(project, problem)); + } + + + public static void a(Project project,PsiFile file) { + DaemonCodeAnalyzer analyzer = DaemonCodeAnalyzer.getInstance(project); + if (analyzer instanceof DaemonCodeAnalyzerImpl ex) { + @Nullable Document document = PsiDocumentManager.getInstance(project).getDocument(file); + ex.restart(file); + TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(CodeService.getEditor(project)); + @NotNull List list = ex.getFileLevelHighlights(project, file); + System.out.println(list); + } + } + + @Deprecated + public static void performQuickFix(@NotNull Project project, @NotNull PsiFile file) { + DaemonCodeAnalyzer.getInstance(project).restart(file); + Editor editor = openClassAndGetEditor(project, file); + if (editor == null) { + log.warn("Failed to open file:{} will not perform quick fix...", file); + return; + } + + ApplicationManager.getApplication().runReadAction(() -> { + ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo(); + ShowIntentionsPass.getActionsToShow(editor, file, intentions, -1); + + // 遍历错误意图并尝试应用第一个 + // TODO mason: 目前这里拿到errorFixesToShow为空(不是null,但没有内容...) + for (HighlightInfo.IntentionActionDescriptor actionDes : intentions.errorFixesToShow) { + try { + IntentionAction action = actionDes.getAction(); + if (action.isAvailable(project, editor, file)) { + action.invoke(project, editor, file); + break; // 应用了第一个可用的修复后退出循环 + } + } catch (IncorrectOperationException ex) { + log.error("Error while try to quick fix:{} of project:{}", file, project); + } + } + }); + } + + public static Editor openClassAndGetEditor(@NotNull Project project, @NotNull PsiFile file) { + return ReadAction.compute(() -> { + if (!ApplicationManager.getApplication().isReadAccessAllowed()) { + log.error("Read access is not allowed"); + return null; + } + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + fileEditorManager.openFile(file.getVirtualFile(), true); + Editor editor = fileEditorManager.getSelectedTextEditor(); + if (editor != null && editor.getDocument() == PsiDocumentManager.getInstance(project).getDocument(file)) { + // 此时 editor 是打开的 PsiFile 对应的 Editor + return editor; + } else { + // 如果没有找到对应的 Editor,可能是文件没有正确打开 + return null; + } + }); + } + + public static void quickFix2(Project project, PsiFile psiFile) { + Editor editor = openClassAndGetEditor(project, psiFile); + if (editor == null) { + log.warn("Failed to open file:{} will not perform quick fix...", psiFile); + return; + } + + // 获取所有错误 + DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl) DaemonCodeAnalyzer.getInstance(project); + List errors = DaemonCodeAnalyzerImpl.getHighlights(psiFile.getViewProvider().getDocument(), HighlightSeverity.ERROR, project); + for (HighlightInfo error : errors) { + if (error.getSeverity() == HighlightSeverity.ERROR) { + // 获取并尝试执行快速修复 + List quickFixes = error.quickFixActionRanges.stream() + .map(range -> range.getFirst().getAction()) + .toList(); + for (IntentionAction quickFix : quickFixes) { + if (quickFix.isAvailable(project, editor, psiFile)) { + quickFix.invoke(project, editor, psiFile); + break; // 只执行第一个可用的快速修复 + } + } + } + } + } + + public static List findAllErrors(Project project, PsiFile psiFile) { + Editor editor = openClassAndGetEditor(project, psiFile); + if (editor == null) { + log.warn("Failed to open file:{} will not perform quick fix...", psiFile); + return Collections.emptyList(); + } + return DaemonCodeAnalyzerImpl.getHighlights(psiFile.getViewProvider().getDocument(), HighlightSeverity.ERROR, project); + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/RobotService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/RobotService.java similarity index 59% rename from athena-all/src/main/java/run/mone/m78/ip/service/RobotService.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/RobotService.java index 3c2b0070e..7db1db631 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/RobotService.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/RobotService.java @@ -1,28 +1,39 @@ -package run.mone.m78.ip.service; +package com.xiaomi.youpin.tesla.ip.service; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; import com.google.gson.Gson; +import com.google.gson.JsonObject; import com.intellij.ide.BrowserUtil; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.ui.Messages; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.RobotContext; +import com.xiaomi.youpin.tesla.ip.bo.RobotReq; +import com.xiaomi.youpin.tesla.ip.bo.robot.AiChatMessage; +import com.xiaomi.youpin.tesla.ip.client.MyHttpClient; +import com.xiaomi.youpin.tesla.ip.common.ChromeUtils; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.util.*; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.mutable.Mutable; import org.apache.commons.lang.mutable.MutableObject; import org.jetbrains.annotations.NotNull; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.RobotContext; -import run.mone.m78.ip.bo.RobotReq; -import run.mone.m78.ip.common.ChromeUtils; -import run.mone.m78.ip.util.*; +import run.mone.ultraman.AthenaContext; import run.mone.ultraman.background.AthenaTask; import run.mone.ultraman.common.GitProjectOpener; +import run.mone.ultraman.http.HttpClient; import run.mone.ultraman.service.AthenaCodeService; import java.io.IOException; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -93,6 +104,7 @@ public static String createPackage(RobotContext context, RobotReq req) { public static String generateMoonHandler(RobotContext context, RobotReq req) { ApplicationManager.getApplication().invokeLater(() -> { + // todo 具体的业务逻辑用req中用户的定义 CodeService.generateMoonHandler(ProjectUtils.projectFromManager()); }); return "ok"; @@ -219,7 +231,6 @@ public static void terminal(RobotContext context, RobotReq req) { ApplicationManager.getApplication().invokeLater(() -> TerminalUtils.send(req.getProject(), req.getParam())); } - //同声翻译 public static void translate(RobotContext context, RobotReq req) { ApplicationManager.getApplication().invokeLater(() -> { @@ -234,7 +245,14 @@ public static void translate(RobotContext context, RobotReq req) { //官网检索 public static void web123(RobotContext context, RobotReq req) { - + ApplicationManager.getApplication().invokeLater(() -> { + Map map = new HashMap<>(); + map.put("code", req.getParam()); + String res = AthenaCodeService.callProxy(req.getProject(), map, "web123", 10).value(); + System.out.println(res); + ChromeUtils.call(req.getProject().getName(), res, 0); + } + ); } @@ -249,16 +267,34 @@ public static void openApp(RobotContext context, RobotReq req) { //错误分析 public static void troubleshoot(RobotContext context, RobotReq req) { + ApplicationManager.getApplication().invokeLater(() -> { + String promptName = "other"; + String troubleshootType = getTroubleshootType(context, req); + if (troubleshootType.contains("dubbo")) { + promptName = "dubbo_troubleshoot"; + } /*else if (troubleshootType.contains("nacos")){ + promptName = "nacos_troubleshoot"; + }*/ else { + promptName = "troubleshoot"; + } + Map map = new HashMap<>(); + map.put("errorMsg", req.getParam()); + String res = AthenaCodeService.callProxy(req.getProject(), map, promptName, 10).value(); + System.out.println(promptName + ":" + res); + ChromeUtils.call(req.getProject().getName(), res, 0); + }); } public static String getTroubleshootType(RobotContext context, RobotReq req) { - return ""; + Map map = new HashMap<>(); + map.put("errorMsg", req.getParam()); + return AthenaCodeService.callProxy(req.getProject(), map, "type_troubleshoot", 10).value(); } public static String getPromptCmd(String cmd) { - return ""; + return CodeService.call("bot", ImmutableMap.of("code", cmd)).trim(); } @@ -268,27 +304,107 @@ public static String getPromptCmd(String cmd) { * @param req */ private static void bot0(GenerateCodeReq req) { + try { + String res = CodeService.call(req.getPromptName(), req.getParam()).trim(); + UltramanConsole.append(req.getProject(), "bot:\n" + res + "\n"); + + if (res.equals("scroll")) { + RobotService.scroll(null, RobotReq.builder().project(req.getProject()).build()); + } + + if (res.startsWith("translate")) { + RobotService.translate(null, RobotReq.builder().project(req.getProject()).param(res.substring(10)).build()); + } + + if (res.startsWith("web123")) { + RobotService.web123(null, RobotReq.builder().project(req.getProject()).param(res.substring(7)).build()); + } + + if (res.equals("generate interface")) { + dynamicCallPrompt(req, "generateInterface"); + } + //执行脚本(所有代码存储在z平台) + if (res.startsWith("run script")) { + Map map = Maps.newHashMap(); + setKV(map, req); + Object r = runScript(map, res); + if (null != r) { + if (r instanceof Throwable t) { + ChromeUtils.call(req.getProject().getName(), "error:" + t.getMessage(), "", 0); + } else if (r instanceof AiChatMessage am) { + ChromeUtils.call(req.getProject().getName(), am); + } else { + ChromeUtils.call(req.getProject().getName(), r.toString(), "", 0); + } + } + return; + } + + + if (res.equals("unsupport")) { + ChromeUtils.call(req.getProject().getName(), "这个指令不支持", "", 0); + } else { + if (req.getParam().get("code").equals("帮助")) { + ChromeUtils.call(req.getProject().getName(), res, "", 0); + } else { + ChromeUtils.call(req.getProject().getName(), "指令:" + res + "执行成功", "", 0); + } + } + } catch (Throwable ex) { + String message = ex.getMessage(); + ChromeUtils.call(req.getProject().getName(), "调用指令的时候发生错误:" + message, "", 0); + log.error(ex.getMessage(), ex); + } } //执行脚本 public static Object runScript(Map map, String promptCmd) { - return null; + String[] ss = promptCmd.split("\\$\\$"); + Arrays.stream(ss).forEach(it -> { + String[] kv = it.split("#"); + if (kv.length == 2) { + map.put(kv[0], kv[1]); + } + }); + if (ss.length == 1) { + map.put("methodName", ss[0]); + } + log.info("map:{}", map); + String methodName = map.get("methodName").toString(); + String httpRes = HttpClient.get(AthenaContext.ins().getZAddr() + "/api/z/open/function/query?name=" + methodName); + JsonObject jsonObject = new Gson().fromJson(httpRes, JsonObject.class); + String functionCode = jsonObject.getAsJsonObject("data").get("scriptContent").getAsString(); + Object r = ScriptService.ins().invoke(functionCode, "call", makeBindMap(), map); + return r; } public static Object runScriptMethod(Map map, String methodName) { - return null; + String httpRes = HttpClient.get(AthenaContext.ins().getZAddr() + "/api/z/open/function/query?name=" + methodName); + JsonObject jsonObject = new Gson().fromJson(httpRes, JsonObject.class); + String functionCode = jsonObject.getAsJsonObject("data").get("scriptContent").getAsString(); + Object r = ScriptService.ins().invoke(functionCode, "call", makeBindMap(), map); + return r; } private static Map makeBindMap() { return ImmutableMap.of( "log", log, - "gson", gson + "gson", gson, + "zAddr", Prompt.getzAddr(), + "ztoken", ConfigUtils.getConfig().getzToken(), + "okHttpClient", MyHttpClient.getInstance() ); } private static void setKV(Map map, GenerateCodeReq req) { - + map.put("classCode", req.getClassCode()); + map.put("methodCode", req.getMethodCode()); + map.put("fileText", req.getVirtualFileText()); + map.put("project", req.getProject()); + map.put("req", req); + map.put("editor", req.getEditor()); + map.put("zToken", ConfigUtils.getConfig().getzToken()); } @@ -305,7 +421,16 @@ public void run(@NotNull ProgressIndicator indicator) { } public static void dynamicCallPrompt(GenerateCodeReq req, String promptName) { - + ApplicationManager.getApplication().invokeLater(() -> { + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + PromptType promptType = Prompt.getPromptType(promptInfo); + PromptService.dynamicInvoke(GenerateCodeReq.builder() + .project(req.getProject()) + .promptName(promptInfo.getPromptName()) + .promptInfo(promptInfo) + .promptType(promptType) + .build()); + }); } diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ScriptService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ScriptService.java similarity index 64% rename from athena-all/src/main/java/run/mone/m78/ip/service/ScriptService.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ScriptService.java index f2a4b4d18..39f9bafb7 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/ScriptService.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/ScriptService.java @@ -14,11 +14,14 @@ * limitations under the License. */ -package run.mone.m78.ip.service; +package com.xiaomi.youpin.tesla.ip.service; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.common.Prompt; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import java.util.Map; @@ -41,7 +44,11 @@ private ScriptService() { @SneakyThrows public static String getScript(String name) { - return ""; + PromptInfo info = Prompt.getPrompt(69, name); + if (null == info || null == info.getData()) { + throw new RuntimeException("No corresponding prompt found."); + } + return info.getData(); } private static final class LazyHolder { @@ -53,7 +60,16 @@ public static ScriptService ins() { } public Object invoke(String script, String functionName, Map bindValues, Object... args) { - return null; + try { + bindValues.entrySet().stream().forEach(it -> engine.put(it.getKey(), it.getValue())); + engine.eval(script); + Object res = ((Invocable) engine).invokeFunction(functionName, args); + log.info("invoke res:" + res); + return res; + } catch (Throwable e) { + log.error("invoke script error:" + e.getMessage(), e); + return e; + } } } diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/SpiderService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/SpiderService.java similarity index 57% rename from athena-all/src/main/java/run/mone/m78/ip/service/SpiderService.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/SpiderService.java index 3333e3030..42b6a26d4 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/SpiderService.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/SpiderService.java @@ -14,12 +14,17 @@ * limitations under the License. */ -package run.mone.m78.ip.service; +package com.xiaomi.youpin.tesla.ip.service; import com.google.gson.Gson; -import run.mone.m78.ip.bo.SpiderUrl; +import com.xiaomi.youpin.tesla.ip.bo.SpiderUrl; +import com.xiaomi.youpin.tesla.ip.common.ApiCall; +import com.xiaomi.youpin.tesla.ip.common.ApiRes; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * @Author goodjava@qq.com @@ -30,7 +35,12 @@ public class SpiderService { private Gson gson = new Gson(); public List list(String name) { - return null; + ApiCall call = new ApiCall(); + Map m = new HashMap<>(); + m.put("name", name); + String res = call.postCall(ApiCall.SPIDER_API, gson.toJson(m), 3000); + List list = gson.fromJson(res, ApiRes.class).getData(); + return list.stream().map(it -> gson.fromJson(it, SpiderUrl.class)).collect(Collectors.toList()); } } diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ImageService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/TaskService.java similarity index 52% rename from athena-all/src/main/java/run/mone/m78/ip/service/ImageService.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/TaskService.java index 68340dba9..4127368a5 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/ImageService.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/TaskService.java @@ -14,35 +14,29 @@ * limitations under the License. */ -package run.mone.m78.ip.service; +package com.xiaomi.youpin.tesla.ip.service; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.diagnostic.Logger; -import run.mone.m78.ip.common.Context; +import com.google.gson.Gson; +import com.xiaomi.youpin.tesla.ip.common.ApiCall; +import com.xiaomi.youpin.tesla.ip.common.ApiRes; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * @Author goodjava@qq.com - * @Date 2021/11/6 20:23 + * @Date 2021/11/9 14:04 */ -public class ImageService extends AbstractService { - - private static final Logger log = Logger.getInstance(ImageService.class); - - /** - * 使用ide 打开图片 - */ - public void open(String t) { - - } - +public class TaskService { - public void openImage(String url) { + public List tasks(String name) { + ApiCall call = new ApiCall(); + Map m = new HashMap<>(1); + m.put("user", name); + String str = call.postCall(ApiCall.TASK_API, new Gson().toJson(m), 5000); + return new Gson().fromJson(str, ApiRes.class).getData(); } - @Override - public void execute(Context context, AnActionEvent e) { - - this.next(context, e); - } } diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/TextService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/TextService.java new file mode 100644 index 000000000..1529c32f1 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/TextService.java @@ -0,0 +1,106 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileTypes.PlainTextFileType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileFactory; +import com.xiaomi.youpin.tesla.ip.util.PsiClassUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + + +/** + * @author goodjava@qq.com + * @date 2023/5/17 15:46 + */ +@Slf4j +public class TextService { + + + public static void writeContent(Project project, String fileName, String moduleName, Runnable runnable) { + writeContent(project, fileName, moduleName, runnable, null); + } + + + public static String readContent(Project project, String module, String fileName) { + PsiDirectory directory = getPsiDirectory(project, module); + if (null == directory) { + return ""; + } + PsiFile file = directory.findFile(fileName); + if (null == file) { + return ""; + } + return file.getText(); + } + + + public static void writeContent(Project project, String fileName, String moduleName, Runnable runnable, String content) { + String fileContent = getFileContent(content); + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(project); + PsiFile psiFile = psiFileFactory.createFileFromText( + fileName, PlainTextFileType.INSTANCE, fileContent); + + PsiDirectory directory = getPsiDirectory(project, moduleName); + if (null == directory) { + log.info("directory is null moduleName:{}", moduleName); + return; + } + + @Nullable PsiFile file = directory.findFile(fileName); + if (null != file) { + file.delete(); + } + + PsiElement addedFile = directory.add(psiFile); + if (addedFile instanceof PsiFile) { + VirtualFile virtualFile = ((PsiFile) addedFile).getVirtualFile(); + if (virtualFile != null) { + FileEditorManager.getInstance(project).openFile(virtualFile, true); + if (StringUtils.isEmpty(content)) { + runnable.run(); + } + } + } + }); + } + + @NotNull + private static String getFileContent(String content) { + String fileContent = " "; + if (StringUtils.isNotEmpty(content)) { + fileContent = content; + } + return fileContent; + } + + + private static PsiDirectory getPsiDirectory(Project project, String moduleName) { + PsiDirectory directory = PsiClassUtils.getSourceDirectory(project, moduleName); + if (null == directory) { + return null; + } + PsiDirectory resourcesDir = directory.findSubdirectory("resources"); + if (null == resourcesDir) { + directory = directory.createSubdirectory("resources"); + } else { + directory = resourcesDir; + } + PsiDirectory subdirectory = directory.findSubdirectory("athena"); + if (subdirectory != null) { + return subdirectory; + } else { + return directory.createSubdirectory("athena"); + } + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/UltramanService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/UltramanService.java similarity index 75% rename from athena-all/src/main/java/run/mone/m78/ip/service/UltramanService.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/UltramanService.java index 2741f8024..13a7e39a4 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/UltramanService.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/UltramanService.java @@ -1,7 +1,6 @@ -package run.mone.m78.ip.service; +package com.xiaomi.youpin.tesla.ip.service; import com.intellij.openapi.components.ServiceManager; -import run.mone.m78.ip.client.GrpcClient; /** * @Author goodjava@qq.com @@ -16,5 +15,4 @@ static UltramanService getInstance() { void init(); - GrpcClient client(); } diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/UltramanServiceImpl.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/UltramanServiceImpl.java similarity index 52% rename from athena-all/src/main/java/run/mone/m78/ip/service/UltramanServiceImpl.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/UltramanServiceImpl.java index bd84bb934..ab52b867b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/UltramanServiceImpl.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/UltramanServiceImpl.java @@ -1,6 +1,7 @@ -package run.mone.m78.ip.service; +package com.xiaomi.youpin.tesla.ip.service; -import run.mone.m78.ip.client.GrpcClient; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import lombok.Data; import lombok.extern.slf4j.Slf4j; /** @@ -8,18 +9,13 @@ * @Date 2021/11/5 12:38 */ @Slf4j +@Data public class UltramanServiceImpl implements UltramanService { - private GrpcClient grpcClient; private boolean openHttpServer = false; - public UltramanServiceImpl() { - grpcClient = new GrpcClient(); - } - - @Override public void run() { log.info("athena run"); @@ -28,15 +24,14 @@ public void run() { @Override public void init() { log.info("athena service init"); - + ScriptService.ins(); + new Thread(() -> { + try { + Prompt.init(); + } catch (Throwable ex) { + ex.printStackTrace(); + } + }).start(); } - private static void openHttpServer() throws Exception { - - } - - @Override - public GrpcClient client() { - return grpcClient; - } } diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/UserService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/UserService.java similarity index 54% rename from athena-all/src/main/java/run/mone/m78/ip/service/UserService.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/UserService.java index bab7d6118..cbc9b0f0e 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/service/UserService.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/UserService.java @@ -14,15 +14,21 @@ * limitations under the License. */ -package run.mone.m78.ip.service; +package com.xiaomi.youpin.tesla.ip.service; import com.google.gson.Gson; import com.intellij.openapi.actionSystem.AnActionEvent; -import run.mone.m78.ip.bo.UserBo; -import run.mone.m78.ip.common.ApiCall; -import run.mone.m78.ip.common.Context; +import com.xiaomi.youpin.tesla.ip.bo.UserBo; +import com.xiaomi.youpin.tesla.ip.common.ApiCall; +import com.xiaomi.youpin.tesla.ip.common.ApiRes; +import com.xiaomi.youpin.tesla.ip.common.Context; +import com.xiaomi.youpin.tesla.ip.common.Events; +import com.xiaomi.youpin.tesla.ip.common.UltramanEvent; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * @Author goodjava@qq.com @@ -40,7 +46,12 @@ public List users() { public List userBoList() { - return null; + ApiCall apiCall = new ApiCall(); + Map m = new HashMap<>(1); + m.put("cmd","getMembers"); + String res = apiCall.postCall(ApiCall.TASK_API, gson.toJson(m), 5000); + ApiRes ar = gson.fromJson(res,ApiRes.class); + return ar.getData().stream().map(it-> gson.fromJson(it,UserBo.class)).collect(Collectors.toList()); } @@ -49,4 +60,9 @@ public void execute(Context context, AnActionEvent e) { this.next(context, e); } + public static void main(String... args) { + UserService us = new UserService(); + List list = us.userBoList(); + System.out.println(list); + } } diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/XmlService.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/XmlService.java new file mode 100644 index 000000000..1eb0daf4d --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/XmlService.java @@ -0,0 +1,147 @@ +package com.xiaomi.youpin.tesla.ip.service; + +import com.google.common.collect.Maps; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.XmlElementFactory; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.xiaomi.youpin.tesla.ip.dialog.SelectModuleDialog; +import com.xiaomi.youpin.tesla.ip.util.ProjectUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.apache.maven.model.io.xpp3.MavenXpp3Writer; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @author goodjava@qq.com + * @date 2023/5/21 22:07 + */ +public class XmlService { + + /** + * 方便操纵xml,这里的作用是修改maven 中的 pom 加入依赖 + * + * @param project + * @param moduleName + * @param dependency + */ + public static void openMavenPomAndModify(Project project, String moduleName, String dependency) { + String pomFilePath = project.getBasePath() + File.separator + moduleName + File.separator + "pom.xml"; + VirtualFile pomFile = LocalFileSystem.getInstance().findFileByPath(pomFilePath); + if (pomFile != null && !pomFile.isDirectory()) { + OpenFileDescriptor descriptor = new OpenFileDescriptor(project, pomFile); + if (descriptor.canNavigate()) { + descriptor.navigate(true); + } + PsiManager psiManager = PsiManager.getInstance(project); + XmlFile xmlFile = (XmlFile) psiManager.findFile(pomFile); + XmlTag dependenciesTag = xmlFile.getRootTag().findFirstSubTag("dependencies"); + XmlElementFactory factory = XmlElementFactory.getInstance(project); + XmlTag dependencyTag = factory.createTagFromText(dependency); + WriteCommandAction.runWriteCommandAction(project, () -> { + dependenciesTag.addSubTag(dependencyTag, false); + }); + } + + + } + + public static Pair checkPomVersion(Project project, String groupId, String artifactId, String version) { + List modules = ProjectUtils.listAllModules(project).stream().filter(m -> !project.getName().equals(m)).toList(); + Map modulePathMap = Maps.newHashMap(); + modules.forEach(i -> modulePathMap.put(i, project.getBasePath() + File.separator + i + File.separator + "pom.xml")); + // 根目录单独处理一下 + modulePathMap.put(Arrays.stream(project.getBasePath().split("/")) + .reduce((first, second) -> second) + .orElse(""), project.getBasePath() + File.separator + "pom.xml"); + List files = modulePathMap.values().stream().map(File::new).toList(); + for (File pomFile : files) { + try { + MavenXpp3Reader reader = new MavenXpp3Reader(); + Model model = reader.read(new FileReader(pomFile)); + List dependencies = model.getDependencies(); + for (Dependency dependency : dependencies) { + if (dependency.getGroupId().equals(groupId) && + dependency.getArtifactId().equals(artifactId)) { + if (dependency.getVersion().equals(version)) { + // true + return Pair.of(0, "success"); + } + // 修改版本 + dependency.setVersion(version); + Pair writeRes = writeDependency(model, pomFile); + ProjectUtils.openFileByPath(project, pomFile.getPath()); + return writeRes.getKey() == 0 ? Pair.of(0, "您好,您的项目已经添加过miapi的maven包,但它不是最新版本,已为您升级到最新版本\n" + + buildDependencyString(groupId, artifactId, version)) : writeRes; + } + } + // 没有引入 + return insertDependency(project, groupId, artifactId, version, modulePathMap); + } catch (Exception e) { + e.printStackTrace(); + return Pair.of(500, e.getMessage()); + } + } + return Pair.of(0, "success"); + } + + @NotNull + private static Pair insertDependency(Project project, String groupId, String artifactId, String version, Map modulePathMap) throws IOException, XmlPullParserException { + SelectModuleDialog dialog = new SelectModuleDialog(project, ProjectUtils.listAllModules(project)); + dialog.show(); + if (dialog.getExitCode() != 0) { + return Pair.of(0, "success"); + } + MavenXpp3Reader reader = new MavenXpp3Reader(); + String selectedModule = dialog.getSelectedModule(); + String pomFilePath = modulePathMap.get(selectedModule); + Model insertModel = reader.read(new FileReader(pomFilePath)); + Dependency dependency = new Dependency(); + dependency.setVersion(version); + dependency.setArtifactId(artifactId); + dependency.setGroupId(groupId); + insertModel.getDependencies().add(dependency); + Pair writeRes = writeDependency(insertModel, new File(pomFilePath)); + ProjectUtils.openFileByPath(project, pomFilePath); + return writeRes.getKey() == 0 ? Pair.of(0, "您好,您的项目之前没有添加过miapi的maven包,我已经为您添加了,下面是我添加的包\n" + + buildDependencyString(groupId, artifactId, version)) : writeRes; + } + + private static Pair writeDependency(Model model, File pomFile) { + try (FileWriter writer = new FileWriter(pomFile)) { + new MavenXpp3Writer().write(writer, model); + return Pair.of(0, "success"); + } catch (IOException ex) { + ex.printStackTrace(); + return Pair.of(500, ex.getMessage()); + } + } + + private static String buildDependencyString(String groupId, String artifactId, String version) { + return String.format("```\n" + + "\n" + + " \t%s\n" + + " \t%s\n" + + " \t%s\n" + + "", groupId, artifactId, version); + + } + + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/consumer/BotMsgConsumer.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/consumer/BotMsgConsumer.java new file mode 100644 index 000000000..621832b44 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/service/consumer/BotMsgConsumer.java @@ -0,0 +1,107 @@ +package com.xiaomi.youpin.tesla.ip.service.consumer; + +import com.google.common.base.Stopwatch; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.ApplicationManager; +import com.xiaomi.youpin.tesla.ip.bo.Action; +import com.xiaomi.youpin.tesla.ip.bo.AiMessage; +import com.xiaomi.youpin.tesla.ip.bo.AiMessageType; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.M78CodeGenerationInfo; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.NotificationCenter; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.LocalAiService; +import com.xiaomi.youpin.tesla.ip.util.ActionUtils; +import run.mone.ultraman.common.CodeUtils; +import run.mone.ultraman.common.ImportCode; +import run.mone.ultraman.listener.event.TaskEvent; + +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +/** + * @author goodjava@qq.com + * @date 2024/6/18 09:51 + */ +public class BotMsgConsumer implements Consumer { + + private GenerateCodeReq req; + private String out; + private ImportCode importCode; + private Stopwatch sw; + + private StringBuilder sb = new StringBuilder(); + + public BotMsgConsumer(GenerateCodeReq req, String out, ImportCode importCode, Stopwatch sw) { + this.req = req; + this.out = out; + this.importCode = importCode; + this.sw = sw; + } + + @Override + public void accept(AiMessage msg) { + if (out.equals("athena")) { + // 发到Athena + LocalAiService.sendMsg(msg, req.getProject().getName()); + } + if (out.equals("athena_chat")) { + // 发到Athena,非代码,纯聊天 + msg.setCode(false); + LocalAiService.sendMsg(msg, req.getProject().getName()); + } + //实现打字机效果 + if (out.equals("editor")) { + //输出到编辑器 + if (msg.getType().equals(AiMessageType.begin)) { + ApplicationManager.getApplication().getMessageBus().syncPublisher(TaskEvent.TOPIC).onEvent(TaskEvent.builder().message("begin").build()); + ApplicationManager.getApplication().invokeLater(() -> { + if (req.getPromptInfo().getLabelValue(Const.PROMPT_LABEL_TYPE, "comment").equals("comment")) { + //为生成注释做好准备 + CodeService.moveToMethodAndInsertLine(req.getProject()); + } + if (req.getPromptInfo().getLabelValue(Const.PROMPT_LABEL_TYPE, "").equals("method")) { + //不再插入回车 + if (req.getParam().containsKey("__skip_enter")) { + return; + } + //为插入方法做准备(挪动到行尾,然后插入一个回车) + CodeService.moveCaretToEndOfLine(req.getEditor()); + CodeService.writeCode2(req.getProject(), req.getEditor(), "\n"); + } + }); + } + + //这里会插入ide中 + if (msg.getType().equals(AiMessageType.process)) { + importCode.append(msg.getText()); + sb.append(msg.getText()); + } + + //生成代码结束了 + if (msg.getType().equals(AiMessageType.success)) { + ApplicationManager.getApplication().getMessageBus().syncPublisher(TaskEvent.TOPIC).onEvent(TaskEvent.builder().message("end").time(sw.elapsed(TimeUnit.SECONDS)).build()); + if (Action.GENERATE_CODE == ActionUtils.getActionByReq(req)) { + CodeUtils.uploadCodeGenInfo(sb.toString(), getComment(), this.req.getProject().getName(), this.req.getClassName()); + } + } + + //发生了错误 + if (msg.getType().equals(AiMessageType.failure)) { + NotificationCenter.notice(msg.getText(), NotificationType.ERROR); + } + } + } + + private String getComment() { + String comment = ""; + if (null != req.getParam().get(Const.GENERATE_CODE_COMMENT)) { + comment = req.getParam().get(Const.GENERATE_CODE_COMMENT); + }else{ + comment = this.req.getCurrentLine(); + } + return comment; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/BuildUi.form similarity index 99% rename from athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/BuildUi.form index d3e5c1ca3..07d3d8778 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/BuildUi.form @@ -1,5 +1,5 @@ -

+ diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/BuildUi.java similarity index 97% rename from athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/BuildUi.java index f86d2eb85..25659fd45 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/BuildUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/BuildUi.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; -import run.mone.m78.ip.bo.IdeaPluginInfoBo; -import run.mone.m78.ip.bo.PluginDeleteParam; -import run.mone.m78.ip.common.ConfigUtils; -import run.mone.m78.ip.util.XmlUtils; +import com.xiaomi.youpin.tesla.ip.bo.IdeaPluginInfoBo; +import com.xiaomi.youpin.tesla.ip.bo.PluginDeleteParam; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.util.XmlUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.mutable.MutableInt; diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ChatUi.form similarity index 98% rename from athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ChatUi.form index c039b60fd..6227db5e6 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ChatUi.form @@ -1,5 +1,5 @@ - + diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ChatUi.java similarity index 97% rename from athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ChatUi.java index a1a5b9723..396d4af6b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/ChatUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ChatUi.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.LangDataKeys; @@ -25,10 +25,10 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; -import run.mone.m78.ip.bo.Response; -import run.mone.m78.ip.bo.UserVo; -import run.mone.m78.ip.common.ConfigUtils; -import run.mone.m78.ip.common.MessageQueue; +import com.xiaomi.youpin.tesla.ip.bo.Response; +import com.xiaomi.youpin.tesla.ip.bo.UserVo; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.MessageQueue; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CodeGeneratorUi.form similarity index 99% rename from athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CodeGeneratorUi.form index bbec0e6b1..c8584d9c8 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CodeGeneratorUi.form @@ -1,5 +1,5 @@ - + diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CodeGeneratorUi.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CodeGeneratorUi.java index 377e5c8c4..ffa1d2191 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/CodeGeneratorUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CodeGeneratorUi.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import run.mone.m78.ip.generator.ClassGenerator; -import run.mone.m78.ip.generator.DirectoryGenerator; -import run.mone.m78.ip.generator.FileGenerator; -import run.mone.m78.ip.generator.PomGenerator; +import com.xiaomi.youpin.tesla.ip.generator.ClassGenerator; +import com.xiaomi.youpin.tesla.ip.generator.DirectoryGenerator; +import com.xiaomi.youpin.tesla.ip.generator.FileGenerator; +import com.xiaomi.youpin.tesla.ip.generator.PomGenerator; import org.apache.commons.lang3.StringUtils; import javax.swing.*; @@ -236,6 +236,7 @@ private void generateServicePom(String projectPath, String projectName, String g smpom.put("author", author); smpom.put("plugin", projectName); smpom.put("plugin_url", url); + smpom.put("plugin_class", "com.xiaomi.youpin.tesla.plug.TeslaPlugin"); servicePomGenerator.generator(smpom); } diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ConfigUi.form similarity index 67% rename from athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ConfigUi.form index cd7d4e7c6..5177bdfe5 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ConfigUi.form @@ -1,6 +1,6 @@ - - + + @@ -8,7 +8,7 @@ - + @@ -16,104 +16,82 @@ - - - - - - - - - - - + - + - + - + - + - + - - - + - + - + - - - + - + + + - + - + - + - + - - - + - + + + - + - - - + - + - + - + - + - + - - - - - - - - - + @@ -128,15 +106,6 @@ - - - - - - - - - diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ConfigUi.java similarity index 52% rename from athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ConfigUi.java index 3a2f27b43..ef43b269e 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/ConfigUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/ConfigUi.java @@ -14,21 +14,25 @@ * limitations under the License. */ -package run.mone.m78.ip.ui; - -import run.mone.m78.ip.bo.ZAddrRes; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.bo.TeslaPluginConfig; -import run.mone.m78.ip.common.ConfigUtils; +package com.xiaomi.youpin.tesla.ip.ui; + +import com.google.common.collect.Lists; +import com.xiaomi.youpin.tesla.ip.bo.ModelRes; +import com.xiaomi.youpin.tesla.ip.bo.TeslaPluginConfig; +import com.xiaomi.youpin.tesla.ip.bo.ZAddrRes; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Prompt; import lombok.Getter; import org.apache.commons.lang3.mutable.MutableBoolean; +import run.mone.ultraman.listener.bo.CompletionEnum; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.event.*; +import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; /** * @author goodjava@qq.com @@ -38,20 +42,23 @@ public class ConfigUi extends JDialog { private JPanel contentPane; - private JTextField dashServerTextField; - private JTextField nickNameTextField; private JPasswordField zTokenPassword; @Getter - private JTextField aiProxyTextField; + private JComboBox chatModelComboBox; - @Getter - private JComboBox modelComboBox; private JButton refreshButton; + @Getter + private JComboBox completionMode; + @Getter + private JComboBox noChatModelComboBox; private MutableBoolean modified; + private static final List COMP_MODE_LIST = CompletionEnum.getDisplayList(); + + public ConfigUi(MutableBoolean modified) { this.modified = modified; setContentPane(contentPane); @@ -76,20 +83,28 @@ public void windowClosing(WindowEvent e) { } private void addListener() { - dashServerTextField.getDocument().addDocumentListener(listener); - nickNameTextField.getDocument().addDocumentListener(listener); this.zTokenPassword.getDocument().addDocumentListener(listener); - this.aiProxyTextField.getDocument().addDocumentListener(listener); - this.modelComboBox.addItemListener(itemEvent -> modified.setTrue()); + this.chatModelComboBox.addItemListener(itemEvent -> modified.setTrue()); + this.noChatModelComboBox.addItemListener(itemEvent -> modified.setTrue()); + this.completionMode.addItemListener(itemEvent -> modified.setTrue()); this.refreshButton.addActionListener(actionEvent -> { ZAddrRes res = Prompt.zAddrRes(); - this.dashServerTextField.setText(res.getAthenaDashServer().trim()); - List list = res.getModels().stream().map(it -> it.getValue()).collect(Collectors.toList()); - ComboBoxModel model = new DefaultComboBoxModel<>(list.toArray(String[]::new)); - this.modelComboBox.setModel(model); - if (list.size() > 0) { - this.modelComboBox.setSelectedItem(list.get(0)); + List list = res.getModels().stream().map(ModelRes::getValue).toList(); + ArrayList models = new ArrayList<>(list); + if (!models.contains(Const.USE_BOT_MODEL)) { + models.add(Const.USE_BOT_MODEL); } + ComboBoxModel chatModel = new DefaultComboBoxModel<>(models.toArray(String[]::new)); + ComboBoxModel noChatModel = new DefaultComboBoxModel<>(models.toArray(String[]::new)); + ComboBoxModel compMode = new DefaultComboBoxModel<>(COMP_MODE_LIST.toArray(String[]::new)); + this.chatModelComboBox.setModel(chatModel); + this.noChatModelComboBox.setModel(noChatModel); + if (!models.isEmpty()) { + this.chatModelComboBox.setSelectedItem(models.get(0)); + this.noChatModelComboBox.setSelectedItem(models.get(0)); + } + this.completionMode.setModel(compMode); + this.completionMode.setSelectedItem(COMP_MODE_LIST.get(0)); modified.setTrue(); }); } @@ -116,18 +131,29 @@ public void changedUpdate(DocumentEvent e) { private void init() { try { TeslaPluginConfig config = ConfigUtils.getConfig(); - this.dashServerTextField.setText(config.getDashServer()); - this.nickNameTextField.setText(config.getNickName()); this.zTokenPassword.setText(config.getzToken()); - this.aiProxyTextField.setText(config.getAiProxy()); List list = config.getModelList(); - String model = config.getModel(); - if (null != list && null != model) { - this.modelComboBox.setModel(new DefaultComboBoxModel(list.toArray(String[]::new))); - this.modelComboBox.setSelectedItem(model); + + // 聊天模型设置 + String chatModel = config.getModel(); + if (null != list && null != chatModel) { + if (!list.contains(Const.USE_BOT_MODEL)) { + list.add(Const.USE_BOT_MODEL); + } + this.chatModelComboBox.setModel(new DefaultComboBoxModel(list.toArray(String[]::new))); + this.chatModelComboBox.setSelectedItem(chatModel); } + // 非聊天模型设置 + String noChatModel = config.getNoChatModel(); + if (null != list && null != noChatModel) { + this.noChatModelComboBox.setModel(new DefaultComboBoxModel(list.toArray(String[]::new))); + this.noChatModelComboBox.setSelectedItem(noChatModel); + } + this.completionMode.setModel(new DefaultComboBoxModel<>(COMP_MODE_LIST.toArray(String[]::new))); + this.completionMode.setSelectedItem(config.getCompletionMode().getDesc()); + } catch (Exception ignore) { } @@ -149,18 +175,6 @@ public MutableBoolean getModified() { } - public JTextField getDashServerTextField() { - return dashServerTextField; - } - - public void setDashServerTextField(JTextField dashServerTextField) { - this.dashServerTextField = dashServerTextField; - } - - public JTextField getNickNameTextField() { - return nickNameTextField; - } - public JPasswordField getzTokenPassword() { return zTokenPassword; } diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CreateClassUi.form similarity index 99% rename from athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CreateClassUi.form index a0f99da4f..7e9a348bb 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CreateClassUi.form @@ -1,5 +1,5 @@ - + diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CreateClassUi.java similarity index 93% rename from athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CreateClassUi.java index 96a901e5c..66f490059 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/CreateClassUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/CreateClassUi.java @@ -1,11 +1,11 @@ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; import com.google.common.collect.Lists; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; -import run.mone.m78.ip.bo.CreateClassRes; -import run.mone.m78.ip.util.PsiClassUtils; -import run.mone.m78.ip.util.ScreenSizeUtils; +import com.xiaomi.youpin.tesla.ip.bo.CreateClassRes; +import com.xiaomi.youpin.tesla.ip.util.PsiClassUtils; +import com.xiaomi.youpin.tesla.ip.util.ScreenSizeUtils; import lombok.Getter; import org.apache.commons.lang3.StringUtils; diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/FilterUi.form similarity index 99% rename from athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/FilterUi.form index e15e3e649..39eb94311 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/FilterUi.form @@ -1,5 +1,5 @@ - + diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/FilterUi.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/FilterUi.java index 665493066..6bf213fbd 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/FilterUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/FilterUi.java @@ -14,18 +14,19 @@ * limitations under the License. */ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import run.mone.m78.ip.generator.ClassGenerator; -import run.mone.m78.ip.generator.DirectoryGenerator; -import run.mone.m78.ip.generator.FileGenerator; -import run.mone.m78.ip.generator.PomGenerator; +import com.xiaomi.youpin.tesla.ip.generator.ClassGenerator; +import com.xiaomi.youpin.tesla.ip.generator.DirectoryGenerator; +import com.xiaomi.youpin.tesla.ip.generator.FileGenerator; +import com.xiaomi.youpin.tesla.ip.generator.PomGenerator; import org.apache.commons.lang3.StringUtils; import javax.swing.*; import java.awt.event.*; +import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/NaviUi.form similarity index 99% rename from athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/NaviUi.form index 1dd308bb3..1d1133e2b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/NaviUi.form @@ -1,5 +1,5 @@ - + diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/NaviUi.java similarity index 99% rename from athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/NaviUi.java index cd0e53ebd..7999c5942 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/NaviUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/NaviUi.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SelectUi.form similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SelectUi.form index 88be74103..df120e75a 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SelectUi.form @@ -1,5 +1,5 @@ - + diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SelectUi.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SelectUi.java index a07ff7e60..af4817579 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/SelectUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SelectUi.java @@ -1,7 +1,7 @@ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; import com.intellij.openapi.ui.Messages; -import run.mone.m78.ip.util.ProjectUtils; +import com.xiaomi.youpin.tesla.ip.util.ProjectUtils; import javax.swing.*; import java.awt.*; diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SpringBootProGenerator.form similarity index 99% rename from athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SpringBootProGenerator.form index aeb5e2e35..45b6cfe8c 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SpringBootProGenerator.form @@ -1,5 +1,5 @@ - + diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SpringBootProGenerator.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SpringBootProGenerator.java index d464e2d8a..666acd6ba 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/SpringBootProGenerator.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/SpringBootProGenerator.java @@ -14,17 +14,13 @@ * limitations under the License. */ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; +import com.xiaomi.youpin.tesla.ip.common.FileUtils; +import com.xiaomi.youpin.tesla.ip.generator.*; import org.apache.commons.lang3.StringUtils; -import run.mone.m78.ip.common.ColorEggUtils; -import run.mone.m78.ip.common.FileUtils; -import run.mone.m78.ip.generator.ClassGenerator; -import run.mone.m78.ip.generator.DirectoryGenerator; -import run.mone.m78.ip.generator.FileGenerator; -import run.mone.m78.ip.generator.PomGenerator; import javax.swing.*; import java.awt.event.*; @@ -176,7 +172,7 @@ private void onOK() { String str = FileUtils.renderTemplate(template, new HashMap<>()); FileUtils.writeFile(catAppdatas + File.separator + "client.xml", str); - colorEgg(projectPath, projectName, testPath, packagePath); +// colorEgg(projectPath, projectName, testPath, packagePath); if (null != project) { Messages.showMessageDialog(project, "Success", "Generate Success", null); @@ -373,23 +369,19 @@ private void generateDeploy(String projectPath, String projectName, String versi deployGenerator.generator(smpom); } - private void colorEgg(String projectPath, String projectName, String testPath, String packagePath) { - String data = ""; - - String str = ColorEggUtils.parseByte2HexStr(ColorEggUtils.encrypt(data, "xiaomiYP")); - - - FileGenerator mdGenerator = new FileGenerator(projectPath, projectName, projectName + "-api" + - File.separator + testPath + File.separator + packagePath + File.separator + "test" + File.separator + ".des", "springboot_color_egg.tml"); - Map smpom = new HashMap<>(); - smpom.put("data", str); - mdGenerator.generator(smpom); - } - - private void onCancel() { dispose(); } + public static void main(String[] args) { + SpringBootProGenerator dialog = new SpringBootProGenerator(null); + dialog.pack(); + // 设置对话框大小是否可改变 + dialog.setResizable(true); + dialog.setSize(500, 400); + dialog.setVisible(true); + System.exit(0); + + } } diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/TaskCreateUi.form similarity index 98% rename from athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/TaskCreateUi.form index f2e836a88..6c3aacf86 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/TaskCreateUi.form @@ -1,5 +1,5 @@ - + diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/TaskCreateUi.java similarity index 90% rename from athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/TaskCreateUi.java index c70f457ad..685f8d54f 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/TaskCreateUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/TaskCreateUi.java @@ -1,10 +1,10 @@ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; import com.google.gson.Gson; -import run.mone.m78.ip.bo.UserBo; -import run.mone.m78.ip.common.ApiCall; -import run.mone.m78.ip.common.ConfigUtils; -import run.mone.m78.ip.service.UserService; +import com.xiaomi.youpin.tesla.ip.bo.UserBo; +import com.xiaomi.youpin.tesla.ip.common.ApiCall; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.service.UserService; import javax.swing.*; import java.awt.event.ActionEvent; diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanConsoleUi.form similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanConsoleUi.form index 8e9b94cee..57e50fcfb 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanConsoleUi.form @@ -1,5 +1,5 @@ - + diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanConsoleUi.java similarity index 98% rename from athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanConsoleUi.java index fb405668c..1bcd316cb 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanConsoleUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanConsoleUi.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.PopupChooserBuilder; diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanTreeUi.form similarity index 97% rename from athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanTreeUi.form index 8aad5a470..3e10bcccf 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanTreeUi.form @@ -1,5 +1,5 @@ - + diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanTreeUi.java similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanTreeUi.java index 73e5bb301..4724ae570 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanTreeUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/UltramanTreeUi.java @@ -1,13 +1,12 @@ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; import com.google.gson.Gson; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.bo.TbTask; -import run.mone.m78.ip.common.ApiCall; -import run.mone.m78.ip.common.ConfigUtils; -import run.mone.m78.ip.listener.TreeMouseClickedListener; -import run.mone.m78.ip.listener.UltrmanTreeKeyAdapter; -import run.mone.m78.ip.util.ScreenSizeUtils; +import com.xiaomi.youpin.tesla.ip.bo.TbTask; +import com.xiaomi.youpin.tesla.ip.common.ApiCall; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.listener.UltrmanTreeKeyAdapter; +import com.xiaomi.youpin.tesla.ip.util.ScreenSizeUtils; import run.mone.ultraman.AthenaContext; import javax.swing.*; @@ -80,7 +79,6 @@ public void windowClosing(WindowEvent e) { ui.requestFocus(); }); - tree1.addMouseListener(new TreeMouseClickedListener(tree1, textField1, popupMenu)); UltrmanTreeKeyAdapter adapter = new UltrmanTreeKeyAdapter(this.project, textField1, tree1, this.webPannel, this.treePannel); AthenaContext.ins().setAthenaTreeKeyAdapter(adapter); textField1.addKeyListener(adapter); diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.form b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/VersionUi.form similarity index 89% rename from athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.form rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/VersionUi.form index fb591a721..d8cc633c2 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.form +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/VersionUi.form @@ -1,9 +1,9 @@ - + - + @@ -31,7 +31,7 @@ - + diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/VersionUi.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/VersionUi.java index 2ca8886e7..9b199b46b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/VersionUi.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/ui/VersionUi.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package run.mone.m78.ip.ui; +package com.xiaomi.youpin.tesla.ip.ui; -import run.mone.m78.ip.util.ScreenSizeUtils; +import com.xiaomi.youpin.tesla.ip.util.ScreenSizeUtils; import javax.swing.*; import java.awt.event.*; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ActionUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ActionUtils.java new file mode 100644 index 000000000..325199dbc --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ActionUtils.java @@ -0,0 +1,28 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import com.xiaomi.youpin.tesla.ip.bo.Action; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.common.Const; + +public class ActionUtils { + + public static Action getActionByReq(GenerateCodeReq req){ + if (req.getPromptInfo().getLabels().getOrDefault("selectComment", "").equals("true")) { + return Action.GENERATE_CODE; + } else if (Const.ATHENA_CHAT.equals(req.getPromptInfo().getPromptName())) { + return Action.CHAT; + } else if (Const.GENERATE_UNIT_TEST.equals(req.getPromptInfo().getPromptName())) { + return Action.UNIT_TEST; + } else if (req.getPromptInfo().getLabels().containsKey("git_push")) { + return Action.GIT_PUSH; + } else if (req.getPromptInfo().getLabels().containsKey("modify_method_name")) { + return Action.SMART_NAMING; + } else if (req.getPromptInfo().getLabelValue("action", "").equals("bug_fix")) { + return Action.BUG_FIX; + } else if(Const.CODE_REVIEW.equals(req.getPromptInfo().getPromptName())) { + return Action.CODE_SUGGESTION; + }else{ + return Action.GENERATE_COMMENT; + } + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/AnnoUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/AnnoUtils.java similarity index 91% rename from athena-all/src/main/java/run/mone/m78/ip/util/AnnoUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/AnnoUtils.java index 3344bee48..8387ad178 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/AnnoUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/AnnoUtils.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; @@ -6,7 +6,7 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.AnnotatedElementsSearch; -import run.mone.m78.ip.bo.ClassInfo; +import com.xiaomi.youpin.tesla.ip.bo.ClassInfo; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; @@ -45,7 +45,7 @@ public static List findClassWithAnno(Project project, String name, St if (annotationClass != null && annotationClass.isAnnotationType()) { AnnotatedElementsSearch.searchPsiClasses(annotationClass, scope).forEach(psiClass -> { Module module = PsiClassUtils.getModule(project, psiClass); - ClassInfo classInfo = ClassInfo.builder().className(psiClass.getQualifiedName()).moduleName(module.getName()).build(); + ClassInfo classInfo = ClassInfo.builder().className(psiClass.getQualifiedName()).simpleName(psiClass.getName()).moduleName(module.getName()).build(); result.add(classInfo); }); } diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/EditorUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/EditorUtils.java new file mode 100644 index 000000000..01b47868a --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/EditorUtils.java @@ -0,0 +1,350 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.*; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.testFramework.LightVirtualFile; +import com.xiaomi.youpin.tesla.ip.common.Const; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/4/18 00:13 + */ +public class EditorUtils { + + public static void scroll(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + editor.getScrollingModel().scrollToCaret(ScrollType.CENTER_DOWN); // 翻到下一页 + } + + public static String getSelectContent(Editor editor) { + return getSelectedContentOrLine(editor, true); + } + + + //获取当前行内容(class) + public static String getCurrentLineContent(Editor editor) { + if (editor == null) { + return ""; + } + Document document = editor.getDocument(); + int caretOffset = editor.getCaretModel().getOffset(); + int lineNumber = document.getLineNumber(caretOffset); + int lineStartOffset = document.getLineStartOffset(lineNumber); + int lineEndOffset = document.getLineEndOffset(lineNumber); + return document.getText(new TextRange(lineStartOffset, lineEndOffset)).trim(); + } + + /** + * 获取编辑器选中内容或者当前行 + */ + public static String getSelectedContentOrLine(Editor editor, boolean selectLine) { + try { + Document document = editor.getDocument(); + final SelectionModel selectionModel = editor.getSelectionModel(); + final int start = selectionModel.getSelectionStart(); + final int end = selectionModel.getSelectionEnd(); + TextRange range = new TextRange(start, end); + String selectTxt = document.getText(range); + + //没有选中任何东西,则选中那一行 + if (StringUtils.isEmpty(selectTxt) && selectLine) { + selectionModel.selectLineAtCaret(); + final int start1 = selectionModel.getSelectionStart(); + final int end1 = selectionModel.getSelectionEnd(); + TextRange range1 = new TextRange(start1, end1); + selectTxt = document.getText(range1); + if (null != selectTxt) { + return selectTxt.trim(); + } + } + return selectTxt; + } catch (Throwable ignore) { + return ""; + } + } + + public static Editor getEditorFromPsiClass(Project project, PsiClass psiClass) { + PsiFile psiFile = psiClass.getContainingFile(); + if (psiFile != null) { + String fileName = psiFile.getName(); + PsiFile[] files = FilenameIndex.getFilesByName(project, fileName, GlobalSearchScope.allScope(project)); + for (PsiFile file : files) { + VirtualFile virtualFile = file.getVirtualFile(); + if (virtualFile != null) { + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + return fileEditorManager.openTextEditor(new OpenFileDescriptor(project, virtualFile), true); + } + } + } + return null; + } + + /** + * 移动到最后一个方法的最后部 + * + * @param psiClass + * @param editor + */ + public static void moveToLastMethodEnd(PsiClass psiClass, Editor editor) { + PsiMethod @NotNull [] methods = psiClass.getMethods(); + int offset = 0; + if (methods.length == 0) { + offset = psiClass.getTextRange().getEndOffset() - 1; + } else { + PsiMethod psiMethod = methods[methods.length - 1]; + offset = psiMethod.getTextRange().getEndOffset(); + } + editor.getCaretModel().moveToOffset(offset); + } + + public static void closeEditor(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (null != editor) { + FileEditorManager manager = FileEditorManager.getInstance(project); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + manager.closeFile(psiFile.getVirtualFile()); + } + } + + public static void openEditor(Project project, String content, String name) { + VirtualFile virtualFile = new LightVirtualFile(name, content); + virtualFile.putUserData(Const.T_KEY, name); + ApplicationManager.getApplication().runWriteAction((Computable) () -> { + Document document = FileDocumentManager.getInstance().getDocument(virtualFile); + if (document != null) { + document.setText(content); + } + return FileEditorManager.getInstance(project).openFile(virtualFile, true); + }); + } + + public static Editor getEditor(Project project) { + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + return editor; + } + + + /** + * 获取或打开指定名称和内容的编辑器。 + * 如果已经存在打开的编辑器,则返回该编辑器,否则打开一个新的编辑器。 + * 如果打开的文件扩展名为"md",则返回该编辑器。 + * + * @param project 项目对象 + * @param name 文件名称 + * @param content 文件内容 + * @return 编辑器对象 + */ + public static Editor getOrOpenEditor(Project project, String name, String content) { + Editor editor = getEditor(project); + if (null == editor || !FileDocumentManager.getInstance().getFile(editor.getDocument()).equals("md")) { + openEditor(project, content, name); + } else { + return editor; + } + return getEditor(project); + } + + + public static int moveCursorToMethodEndIfOutside(Editor editor, PsiMethod method, int cursorOffset) { + // 获取当前编辑器 + if (editor == null) { + return cursorOffset; + } + + // 获取方法体的起始和结束偏移量 + PsiElement methodBody = method.getBody(); + if (methodBody == null) { + return cursorOffset; + } + int methodStartOffset = methodBody.getTextRange().getStartOffset(); + int methodEndOffset = methodBody.getTextRange().getEndOffset() - 1; + + // 检查光标是否在方法体内 + if (cursorOffset < methodStartOffset || cursorOffset > methodEndOffset) { + // 光标不在方法体内,移动光标到方法体最后一个字符后面 + ApplicationManager.getApplication().invokeAndWait(() -> { + editor.getCaretModel().moveToOffset(methodEndOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + }); + return methodEndOffset; + } + + Document document = editor.getDocument(); + // 获取当前行号 + int currentLineNumber = document.getLineNumber(cursorOffset); + + int lineStartOffset = document.getLineStartOffset(currentLineNumber); + // 获取当前行的结束偏移量 + int lineEndOffset = document.getLineEndOffset(currentLineNumber); + + // 检查cursorOffset前面是否有字符 + boolean hasCharactersBeforeCursor = cursorOffset > lineStartOffset; + + // 没有在行尾 + if (cursorOffset <= lineEndOffset) { + int num = hasCharactersBeforeCursor ? 1 : 0; + ApplicationManager.getApplication().invokeAndWait(() -> { + if (hasCharactersBeforeCursor) { + WriteCommandAction.runWriteCommandAction(editor.getProject(), () -> editor.getDocument().insertString(lineEndOffset, "\n")); + } + editor.getCaretModel().moveToOffset(lineEndOffset + num); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + }); + return lineEndOffset + num; + } + + return cursorOffset; + } + + public static String getFirstClassName(PsiFile psiFile) { + PsiClass psiClass = PsiTreeUtil.findChildOfType(psiFile, PsiClass.class); + if (psiClass != null) { + return psiClass.getName(); + } + return null; + } + + //鼠标移动到注释末尾 + public static void moveCaretToCommentEnd(@NotNull Project project, @NotNull PsiComment comment) { + // 获取编辑器 + PsiFile file = comment.getContainingFile(); + if (file == null) return; + + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (editor == null) return; + + // 获取注释的结束偏移量 + int endOffset = comment.getTextRange().getEndOffset(); + + // 移动光标到注释的末尾 + editor.getCaretModel().moveToOffset(endOffset); + editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); + } + + //基于鼠标位置判断是否是注释,并将光标移动到注释末尾 + public static void moveCaretToCommentEnd(Editor editor) { + // 获取光标的逻辑位置 + LogicalPosition logicalPosition = editor.getCaretModel().getLogicalPosition(); + int offset = editor.logicalPositionToOffset(logicalPosition); + // 获取当前文件 + Document document = editor.getDocument(); + // 检查光标是否在多行注释中 + PsiFile psiFile = PsiDocumentManager.getInstance(editor.getProject()).getPsiFile(document); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiComment comment = PsiTreeUtil.getParentOfType(elementAtCaret, PsiComment.class); + + if (null != comment) { + EditorUtils.moveCaretToCommentEnd(editor.getProject(), comment); + } + } + + public static boolean isNotClassHeaderComment(@NotNull PsiComment comment) { + PsiElement parent = comment.getParent(); + if (parent instanceof PsiClass) { + PsiClass psiClass = (PsiClass) parent; + PsiElement firstElement = psiClass.getFirstChild(); + if (firstElement instanceof PsiComment && firstElement == comment) { + return false; + } + } + return true; + } + + + // PsiComment是否在方法体内 + public static boolean isCommentInsideMethod(@NotNull PsiComment comment) { + PsiMethod psiMethod = PsiTreeUtil.getParentOfType(comment, PsiMethod.class); + return psiMethod != null; + } + + public static boolean isNotLicenseComment(@NotNull PsiComment comment) { + PsiFile file = comment.getContainingFile(); + if (file != null) { + PsiElement firstElement = file.getFirstChild(); + if (firstElement instanceof PsiComment && firstElement == comment) { + return false; + } + } + return true; + } + + //PsiComment是否在class范围内 + public static boolean isCommentInsideClass(@NotNull PsiComment comment) { + PsiClass psiClass = PsiTreeUtil.getParentOfType(comment, PsiClass.class); + return psiClass != null; + } + + //判断当前光标是否在注释上 + public static boolean isCursorInComment(PsiMethod psiMethod) { + Project project = psiMethod.getProject(); + // 获取编辑器 + PsiFile file = psiMethod.getContainingFile(); + if (file == null) return false; + //获取editor + Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); + if (editor == null) return false; + + int offset = editor.getCaretModel().getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(editor.getProject()).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + if (null == elementAtCaret) { + return false; + } + PsiComment comment = PsiTreeUtil.getParentOfType(elementAtCaret, PsiComment.class); + return null != comment; + } + + + + public static boolean isNotMethodComment(@NotNull PsiComment comment) { + return !(comment.getParent() instanceof PsiMethod); + } + + // 判断当前光标位置是否是在注释上,如果是,获取当前PsiComment并返回,如果当前行为空,则获取前一行的PsiComment + public static PsiComment getPsiComment(Editor editor) { + int offset = editor.getCaretModel().getOffset(); + PsiFile psiFile = PsiDocumentManager.getInstance(editor.getProject()).getPsiFile(editor.getDocument()); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiComment comment = PsiTreeUtil.getParentOfType(elementAtCaret, PsiComment.class); + if(comment == null){ + comment = getPreviousLinePsiComment(editor); + } + return comment; + } + + // 获取当前光标前一行的PsiComment + public static PsiComment getPreviousLinePsiComment(Editor editor) { + if (editor == null) { + return null; + } + Document document = editor.getDocument(); + int caretOffset = editor.getCaretModel().getOffset(); + int lineNumber = document.getLineNumber(caretOffset); + if (lineNumber == 0) { + return null; // 光标在第一行,没有前一行 + } + int previousLineStartOffset = document.getLineStartOffset(lineNumber - 1); + PsiFile psiFile = PsiDocumentManager.getInstance(editor.getProject()).getPsiFile(document); + PsiElement elementAtPreviousLine = psiFile.findElementAt(previousLineStartOffset); + return PsiTreeUtil.getParentOfType(elementAtPreviousLine, PsiComment.class); + } +} + +// 快排 diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/FileUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/FileUtils.java similarity index 94% rename from athena-all/src/main/java/run/mone/m78/ip/util/FileUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/FileUtils.java index 88d005ac7..d31478b03 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/FileUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/FileUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import lombok.SneakyThrows; @@ -29,7 +29,7 @@ */ public class FileUtils { - private static String serverUrl = ""; + private static String serverUrl = "http://127.0.0.1:9999"; public static void upload(String name, String path) throws IOException { System.out.println("upload:" + name); diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/FixCodeUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/FixCodeUtils.java new file mode 100644 index 000000000..f5a42048e --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/FixCodeUtils.java @@ -0,0 +1,103 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import lombok.extern.slf4j.Slf4j; +import run.mone.ultraman.bo.AthenaClassInfo; +import run.mone.ultraman.service.AthenaCodeService; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +@Slf4j +public class FixCodeUtils { + + private static final Map BASIC_CLASSES = new HashMap<>(); + + private static final Pattern BO_PATTERN = Pattern.compile("$.\\.bo\\."); + + static { + // 初始化 Java 基础类集合 + BASIC_CLASSES.put("ArrayList", "java.util.ArrayList"); + BASIC_CLASSES.put("List", "java.util.List"); + BASIC_CLASSES.put("Map", "java.util.Map"); + BASIC_CLASSES.put("HashMap", "java.util.HashMap"); + BASIC_CLASSES.put("Serializable", "java.io.Serializable"); + } + + public static boolean isBO(String fqcn) { + Matcher matcher = BO_PATTERN.matcher(fqcn); + return matcher.matches(); + } + + public static String addDataAnnotationForClass(String code, AthenaClassInfo athenaClassInfo) { + //检查import里有没有lombok.Data, 没有则添加import lombok.Data; + if (athenaClassInfo.getImports() != null + && !athenaClassInfo.getImports().contains("lombok.Data")) { + code = addImportStatements(code, Arrays.asList("import lombok.Data;")); + } + + //检查annotations里有没有Data, 没有则添加@Data + if (athenaClassInfo.getAnnoList() != null + && !athenaClassInfo.getAnnoList().contains("Data")) { + code = addAnnotationStatements(code, Arrays.asList("@Data")); + } + + return code; + } + + public static String addBasicImportForClass(String code, AthenaClassInfo athenaClassInfo) { + List existImports = (athenaClassInfo.getImports() == null) ? new ArrayList<>() : athenaClassInfo.getImports(); + List needImports = analyzeBasicClassesUsed(code); + + List importStatements = needImports.stream().filter(it -> !existImports.contains(it)).map(it -> { + return "import " + it + ";"; + }).collect(Collectors.toList()); + + return addImportStatements(code, importStatements); + } + + private static List analyzeBasicClassesUsed(String code) { + return BASIC_CLASSES.entrySet().stream().filter(it -> code.contains(it.getKey())).map(Map.Entry::getValue).collect(Collectors.toList()); + } + + private static String addImportStatements(String code, List importStatements) { + if (importStatements == null || importStatements.size() == 0) { + return code; + } + + int packageIndex = code.indexOf("package "); + int importIndex = code.indexOf("import "); + String tmpImport = importStatements.stream() + .map(importStatement -> importStatement + "\n") + .collect(Collectors.joining()); + // 如果已经存在 import 语句,则将 import 语句插入到第一个 import 语句之前 + if (importIndex != -1) { + return code.substring(0, importIndex) + tmpImport + code.substring(importIndex); + } else if (packageIndex != -1) { + // 如果不存在 import 语句但存在 package 语句,则将 import 语句插入到 package 语句的下一行 + int lineEndIndex = code.indexOf(';', packageIndex); + return code.substring(0, lineEndIndex + 1) + "\n" + tmpImport + code.substring(lineEndIndex + 1); + } else { + // 如果都不存在,则将 import 语句插入到最前面 + return tmpImport + code; + } + } + + private static String addAnnotationStatements(String code, List annotations) { + if (annotations == null || annotations.size() == 0) { + return code; + } + + String tmpAnnotation = annotations.stream() + .map(importStatement -> importStatement + "\n") + .collect(Collectors.joining()); + // 在类定义上方添加注解 + int index = code.indexOf("public class"); + if (index != -1) { + code = code.substring(0, index) + tmpAnnotation + code.substring(index); + } + return code; + } + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/GitUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/GitUtils.java new file mode 100644 index 000000000..6d2f7d764 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/GitUtils.java @@ -0,0 +1,125 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import com.google.common.base.Joiner; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vcs.changes.ChangeListManager; +import lombok.SneakyThrows; + +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/7/8 23:19 + */ +public class GitUtils { + + + /** + * 获取项目中受影响的文件名列表。 + * + * @param project 项目对象 + * @return 受影响的文件名列表 + */ + public static List getAffectedFileNames(Project project) { + ChangeListManager changeListManager = ChangeListManager.getInstance(project); + return changeListManager.getAffectedFiles().stream().map(it -> it.toString()).collect(Collectors.toList()); + } + + public static String getAffectedFileNamesStr(Project project) { + ChangeListManager changeListManager = ChangeListManager.getInstance(project); + List list = changeListManager.getAffectedFiles().stream().map(it -> it.toString()).collect(Collectors.toList()); + return list.stream().collect(Collectors.joining("\n")); + } + + + //获取git地址 + @SneakyThrows + public static String getGitAddress(Project project) { + try { + String path = project.getBasePath(); + path = Joiner.on(File.separator).join(path, ".git", "config"); + return Files.readAllLines(Paths.get(path)).stream().filter(it -> it.contains("url")).map(it -> (it.split("=")[1].trim())).findAny().get(); + } catch (Throwable ignore) { + + } + return ""; + } + + //获取最后一条commit记录 + @SneakyThrows + public static List getLastCommit(Project project) { + List res = new ArrayList<>(); + try { + String path = project.getBasePath(); + path = Joiner.on(File.separator).join(path, ".git"); + Process process = Runtime.getRuntime().exec("git --git-dir=" + path + " log -3 --pretty=format:\"%H\""); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + String line; + int commitCount = 0; + while ((line = reader.readLine()) != null) { + if (commitCount < 3) { + res.add(line); + } else { + break; + } + commitCount++; + } + } + } catch (Throwable e) { + e.printStackTrace(); + } + return res; + } + + public static String getCommitDiff(Project project) { + StringJoiner res = new StringJoiner(System.lineSeparator()); + try { + // 获取diff内容 + String path = project.getBasePath(); + path = Joiner.on(File.separator).join(path, ".git"); + Process diffProcess = Runtime.getRuntime().exec("git --git-dir=" + path + " --work-tree=" + project.getBasePath() + " diff HEAD"); + try (BufferedReader diffReader = new BufferedReader(new InputStreamReader(diffProcess.getInputStream()))) { + String line; + while ((line = diffReader.readLine()) != null) { + res.add(line); + } + } + } catch (Throwable e) { + e.printStackTrace(); + } + return res.toString(); + } + + public static String getCurrentBranch(Project project) { + String branch = ""; + try { + // 执行git命令 + String path = project.getBasePath(); + path = Joiner.on(File.separator).join(path, ".git"); + Process process = Runtime.getRuntime().exec("git --git-dir=" + path + " --work-tree=" + project.getBasePath() + " rev-parse --abbrev-ref HEAD"); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + branch = reader.readLine(); + process.waitFor(); + } catch (Exception e) { + e.printStackTrace(); + } + return branch; + } + + public static String getProjectNameFromGitUrl(String gitUrl) { + String urlWithoutProtocol = gitUrl.replaceFirst("^\\w+://|^\\w+@", ""); + String urlWithoutExtension = urlWithoutProtocol.replaceFirst("\\.git$", ""); + String[] parts = urlWithoutExtension.split("/"); + String projectName = parts[parts.length - 1]; + return projectName; + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/HintUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/HintUtils.java similarity index 86% rename from athena-all/src/main/java/run/mone/m78/ip/util/HintUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/HintUtils.java index 6c9a5aca7..9b759c38f 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/HintUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/HintUtils.java @@ -14,14 +14,18 @@ * limitations under the License. */ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.google.gson.Gson; import com.intellij.codeInsight.hint.HintManager; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; -import run.mone.m78.ip.bo.Result; -import run.mone.m78.ip.common.ChromeUtils; +import com.intellij.openapi.project.Project; +import com.xiaomi.youpin.tesla.ip.bo.Result; +import com.xiaomi.youpin.tesla.ip.common.ChromeUtils; /** * @Author goodjava@qq.com diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ImportUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ImportUtils.java new file mode 100644 index 000000000..3c8e90d5a --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ImportUtils.java @@ -0,0 +1,161 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import com.google.common.base.Splitter; +import com.intellij.codeInsight.actions.OptimizeImportsAction; +import com.intellij.codeInspection.unusedImport.UnusedImportInspection; +import com.intellij.openapi.actionSystem.ActionPlaces; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.impl.source.PsiJavaFileImpl; +import com.intellij.psi.util.PsiTreeUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/6/22 21:41 + */ +@Slf4j +public abstract class ImportUtils { + + public static void removeInvalidImports(Project project, Editor editor) { + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + PsiImportList importList = PsiTreeUtil.findChildOfType(psiFile, PsiImportList.class); + UnusedImportInspection unusedImportInspection = new UnusedImportInspection(); + if (importList != null) { + boolean modify = false; + if (importList != null) { + for (PsiImportStatementBase importStatement : importList.getAllImportStatements()) { + PsiJavaCodeReferenceElement importReference = importStatement.getImportReference(); + if (importReference != null && importReference.resolve() != null && importReference.multiResolve(true).length == 0) { + modify = true; + importStatement.delete(); + } + } + } + if (modify) { + PsiDocumentManager.getInstance(psiFile.getProject()).commitDocument(editor.getDocument()); + } + } + }); + } + + public static void optimizeImports(Project project, Editor editor) { + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + AnActionEvent event = AnActionEvent.createFromDataContext( + ActionPlaces.UNKNOWN, + null, + dataId -> { + if (CommonDataKeys.PSI_FILE.is(dataId)) { + return psiFile; + } else if (CommonDataKeys.PROJECT.is(dataId)) { + return project; + } else if (CommonDataKeys.EDITOR.is(dataId)) { + return editor; + } else { + return null; + } + } + ); + new OptimizeImportsAction().actionPerformed(event); + }); + } + + + public static void addImport(Project project, Editor editor, List importStrList) { + try { + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + Document document = editor.getDocument(); + PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); + PsiImportList importList = PsiTreeUtil.findChildOfType(psiFile, PsiImportList.class); + for (String importStr : importStrList) { + boolean isAlreadyImported = false; + boolean isStatic = false; + String memberName = ""; + if (importStr.contains("static ")) { + isStatic = true; + importStr = importStr.trim().split(" +")[1]; + String[] array = importStr.split("\\."); + importStr = Arrays.stream(array).limit(array.length - 1).collect(Collectors.joining(".")); + memberName = array[array.length - 1]; + } + for (PsiImportStatement importStatement : importList.getImportStatements()) { + String str = importStr; + List list = Splitter.on(" ").splitToList(importStr.replace(";", "")); + if (list.size() > 0) { + str = list.get(list.size() - 1); + } + if (importStatement.getQualifiedName().equals(str)) { + isAlreadyImported = true; + break; + } + } + if (!isAlreadyImported) { + PsiClass psiClass = createPsiClass(factory, importStr); + if (null == psiClass) { + continue; + } + PsiImportStatementBase importStatement = null; + + if (isStatic) { + importStatement = factory.createImportStaticStatement(psiClass, memberName); + } else { + importStatement = factory.createImportStatement(psiClass); + } + + if (importList != null) { + importList.add(importStatement); + PsiDocumentManager.getInstance(psiFile.getProject()).commitDocument(document); + } + } + } + }); + } catch (Throwable ex) { + log.error(ex.getMessage(), ex); + } + } + + public static PsiClass createPsiClass(PsiElementFactory factory, String className) { + try { + String[] array = className.split("\\."); + PsiClass psiClass = factory.createClass(array[array.length - 1]); + PsiJavaFile javaFile = (PsiJavaFile) psiClass.getContainingFile(); + javaFile.setPackageName(Arrays.stream(array).limit(array.length - 1).collect(Collectors.joining("."))); + return psiClass; + } catch (Throwable ex) { + return null; + } + } + + + public static String junitVersion(PsiClass psiClass) { + PsiElement c = psiClass.getParent(); + if (c instanceof PsiJavaFileImpl pfi) { + String text = pfi.getImportList().getText(); + if (StringUtils.isEmpty(text)) { + return "unknow"; + } + if (text.contains("org.junit.Test")) { + return "junit"; + } + if (text.contains("org.junit.jupiter.api.Test")) { + return "jupiter"; + } + } + return "unknow"; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/LabelUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/LabelUtils.java similarity index 88% rename from athena-all/src/main/java/run/mone/m78/ip/util/LabelUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/LabelUtils.java index 9f0961916..0e10a22e4 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/LabelUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/LabelUtils.java @@ -1,11 +1,11 @@ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.google.common.base.Joiner; import com.google.common.collect.Maps; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.bo.ParamDialogReq; -import run.mone.m78.ip.dialog.ParamTableDialog; -import run.mone.m78.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.ParamDialogReq; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.dialog.ParamTableDialog; import java.util.Map; @@ -17,6 +17,7 @@ public class LabelUtils { public static String getLabelValue(Project project, PromptInfo promptInfo, String key, String defaultValue) { + //用户配置的优先级最高 Map map = ResourceUtils.getAthenaConfig(project); String rkey = Joiner.on("@").join(promptInfo.getPromptName(), key); if (map.containsKey(rkey)) { diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/LockUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/LockUtils.java similarity index 85% rename from athena-all/src/main/java/run/mone/m78/ip/util/LockUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/LockUtils.java index 4b76fe0a9..06ae2b58c 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/LockUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/LockUtils.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.intellij.openapi.editor.Editor; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/MarkDownUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/MarkDownUtils.java new file mode 100644 index 000000000..a2c92f123 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/MarkDownUtils.java @@ -0,0 +1,48 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import com.vladsch.flexmark.ast.FencedCodeBlock; +import com.vladsch.flexmark.parser.Parser; +import com.vladsch.flexmark.util.ast.Document; +import com.vladsch.flexmark.util.ast.NodeVisitor; +import com.vladsch.flexmark.util.ast.VisitHandler; +import com.vladsch.flexmark.util.sequence.BasedSequence; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.mutable.Mutable; +import org.apache.commons.lang3.mutable.MutableObject; + +/** + * @author goodjava@qq.com + * @date 2024/3/12 11:07 + */ +public class MarkDownUtils { + + + public static String extractCodeBlock(String markdown) { + try { + // 创建Markdown解析器 + Parser parser = Parser.builder().build(); + Document document = parser.parse(markdown); + Mutable res = new MutableObject<>(""); + // 创建自定义访问者,用于移除所有的代码块 + NodeVisitor visitor = new NodeVisitor(new VisitHandler(FencedCodeBlock.class, node -> { + FencedCodeBlock codeBlock = (FencedCodeBlock) node; + BasedSequence info = codeBlock.getInfo(); + // 检查代码块的语言标记是否为"json" + if (info.equals("json") || info.equals("java")) { + // 如果是,则从文档中移除该代码块 + res.setValue(codeBlock.getChildChars().toString()); + } + })); + + visitor.visit(document); + + if (StringUtils.isNotEmpty(res.getValue())) { + return res.getValue(); + } + return markdown; + } catch (Throwable ignore) { + return markdown; + } + } + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/MarkdownFilter.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/MarkdownFilter.java new file mode 100644 index 000000000..1f537516d --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/MarkdownFilter.java @@ -0,0 +1,62 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import java.util.function.Consumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author goodjava@qq.com + * @date 2024/1/31 11:27 + */ +public class MarkdownFilter { + + + private static final Pattern START_PATTERN = Pattern.compile("```"); + private static final Pattern JAVA_PATTERN = Pattern.compile("\\bjava\\b|\\bgo\\b"); + private static final Pattern END_PATTERN = Pattern.compile("```$"); + private final Consumer codeConsumer; + private boolean inCodeBlock = false; + private boolean checkForJava = false; + + public MarkdownFilter(Consumer codeConsumer) { + this.codeConsumer = codeConsumer; + } + + public void accept(String str) { + if (inCodeBlock) { + Matcher endMatcher = END_PATTERN.matcher(str); + if (endMatcher.find()) { + inCodeBlock = false; + accept(str.substring(endMatcher.end())); + } else { + codeConsumer.accept(str); + } + } else if (checkForJava) { + Matcher javaMatcher = JAVA_PATTERN.matcher(str); + if (javaMatcher.lookingAt()) { + inCodeBlock = true; + // 处理java标记之后的内容 + accept(str.substring(javaMatcher.end())); + } else { + // 如果不是java,则发送之前缓存的```和当前字符串 + codeConsumer.accept("```" + str); + } + checkForJava = false; + } else { + Matcher startMatcher = START_PATTERN.matcher(str); + if (startMatcher.find()) { + checkForJava = true; + // 发送开始标记之前的内容 + codeConsumer.accept(str.substring(0, startMatcher.start())); + // 检查剩余的字符串是否以java开始 + String remaining = str.substring(startMatcher.end()); + if (!remaining.isEmpty()) { + accept(remaining); + } + } else { + codeConsumer.accept(str); + } + } + } + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/NetUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/NetUtils.java new file mode 100644 index 000000000..07eef84e8 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/NetUtils.java @@ -0,0 +1,154 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; + +import java.io.IOException; +import java.net.*; +import java.util.*; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + */ +@Slf4j +public class NetUtils { + + + private static volatile InetAddress LOCAL_ADDRESS = null; + + public static final String LOCALHOST = "127.0.0.1"; + public static final String ANYHOST = "0.0.0.0"; + public static final String DOCKERHOST = "172.17.0.1"; + + public static final String LOCALHOST2 = "192."; + + + + private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$"); + + private static final int RND_PORT_START = 30000; + + private static final int MAX_PORT = 65535; + + private static final Random RANDOM = new Random(System.currentTimeMillis()); + + private static final int RND_PORT_RANGE = 10000; + + + public static String getHostName() { + try { + return InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + log.error("get host name error:{}", e.getMessage()); + return ""; + } + } + + + public static String getLocalHost() { + InetAddress address = getLocalAddress(); + return address == null ? LOCALHOST : address.getHostAddress(); + } + + public static InetAddress getLocalAddress() { + if (LOCAL_ADDRESS != null) { + return LOCAL_ADDRESS; + } + InetAddress localAddress = getLocalAddress0(); + LOCAL_ADDRESS = localAddress; + return localAddress; + } + + private static InetAddress getLocalAddress0() { + InetAddress localAddress = null; + try { + localAddress = InetAddress.getLocalHost(); + if (localAddress instanceof Inet6Address) { + Inet6Address address = (Inet6Address) localAddress; + if (isValidV6Address(address)) { + return normalizeV6Address(address); + } + } else if (isValidAddress(localAddress)) { + return localAddress; + } + } catch (Throwable e) { + log.warn(e.getMessage()); + } + try { + Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); + if (null == interfaces) { + return localAddress; + } + while (interfaces.hasMoreElements()) { + try { + NetworkInterface network = interfaces.nextElement(); + Enumeration addresses = network.getInetAddresses(); + while (addresses.hasMoreElements()) { + try { + InetAddress address = addresses.nextElement(); + if (address instanceof Inet6Address) { + Inet6Address v6Address = (Inet6Address) address; + if (isValidV6Address(v6Address)) { + return normalizeV6Address(v6Address); + } + } else if (isValidAddress(address)) { + return address; + } + } catch (Throwable e) { + log.warn(e.getMessage()); + } + } + } catch (Throwable e) { + log.warn(e.getMessage()); + } + } + } catch (Throwable e) { + log.warn(e.getMessage()); + } + return localAddress; + } + + static boolean isValidV6Address(Inet6Address address) { + boolean preferIpv6 = Boolean.getBoolean("java.net.preferIPv6Addresses"); + if (!preferIpv6) { + return false; + } + try { + return address.isReachable(100); + } catch (IOException e) { + // ignore + } + return false; + } + + static InetAddress normalizeV6Address(Inet6Address address) { + String addr = address.getHostAddress(); + int i = addr.lastIndexOf('%'); + if (i > 0) { + try { + return InetAddress.getByName(addr.substring(0, i) + '%' + address.getScopeId()); + } catch (UnknownHostException e) { + // ignore + log.debug("Unknown IPV6 address: ", e); + } + } + return address; + } + + + static boolean isValidAddress(InetAddress address) { + if (address == null || address.isLoopbackAddress()) { + return false; + } + String name = address.getHostAddress(); + return (name != null + && !ANYHOST.equals(name) + && !LOCALHOST.equals(name) + && !name.startsWith(LOCALHOST2) + && !DOCKERHOST.equals(name) + && IP_PATTERN.matcher(name).matches()); + } + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/Notify.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/Notify.java similarity index 90% rename from athena-all/src/main/java/run/mone/m78/ip/util/Notify.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/Notify.java index 5af8e5c61..3d6acd39b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/Notify.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/Notify.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.intellij.notification.*; @@ -38,6 +38,8 @@ public class Notify { public static void show(@NotNull Project project, @NotNull String title, @NotNull String content, @NotNull NotificationGroup group, @NotNull NotificationType type, @Nullable NotificationListener listener) { + Notification notification = group.createNotification(title, content, type, listener); + Notifications.Bus.notify(notification, project); } public static void show(@NotNull Project project, diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/PackageUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PackageUtils.java similarity index 83% rename from athena-all/src/main/java/run/mone/m78/ip/util/PackageUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PackageUtils.java index a03c0b06e..314fa29b7 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/PackageUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PackageUtils.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.intellij.openapi.project.Project; import com.intellij.psi.JavaPsiFacade; @@ -15,6 +15,13 @@ public class PackageUtils { + /** + * 获取指定项目和包名下的所有类名列表 + * + * @param project 项目对象 + * @param packageName 包名 + * @return 类名列表 + */ public static List getClassList(Project project, String packageName) { PsiPackage psiPackage = JavaPsiFacade.getInstance(project).findPackage(packageName); List result = new ArrayList<>(); diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/ProjectUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ProjectUtils.java similarity index 74% rename from athena-all/src/main/java/run/mone/m78/ip/util/ProjectUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ProjectUtils.java index 2629d93c4..2b12b69af 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/ProjectUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ProjectUtils.java @@ -14,15 +14,21 @@ * limitations under the License. */ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.google.common.collect.Lists; import com.intellij.ide.DataManager; import com.intellij.ide.RecentProjectsManager; import com.intellij.ide.RecentProjectsManagerBase; +import com.intellij.ide.impl.OpenProjectTask; +import com.intellij.ide.plugins.IdeaPluginDescriptor; +import com.intellij.ide.plugins.PluginManager; +import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.openapi.actionSystem.DataConstants; import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; @@ -32,6 +38,7 @@ import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.project.ex.ProjectManagerEx; import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.ModuleRootManager; @@ -42,13 +49,14 @@ import com.intellij.psi.PsiManager; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.util.PsiUtilBase; +import com.xiaomi.youpin.codegen.M78DoceanMongoGen; +import com.xiaomi.youpin.infra.rpc.Result; import org.jetbrains.annotations.Nullable; import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; import java.util.stream.Collectors; /** @@ -70,7 +78,7 @@ public static Project projectFromManager() { } public static Project projectFromManager(String name) { - return null; + return Arrays.stream(ProjectManager.getInstance().getOpenProjects()).filter(it -> it.getName().equals(name)).findFirst().get(); } /** @@ -212,5 +220,43 @@ public static String getModulePath(Project project, String moduleName) { return new File(module.getModuleFilePath()).getParent(); } + public static void openProject(Project project, String projectPathStr) { + ApplicationManager.getApplication().invokeLater(() -> { + // 获取本地文件系统 + ProjectManagerEx projectManager = ProjectManagerEx.getInstanceEx(); + Path projectPath = Paths.get(projectPathStr); + OpenProjectTask openProjectTask = new OpenProjectTask(false, project, true, false); + projectManager.openProject(projectPath, openProjectTask); + }); + } + public Optional generateProjectBase(Project project, String projectName, String packageName, String groupId, String author) { + VirtualFile contentRoot = ProjectRootManager.getInstance(project).getContentRoots()[0]; + String path = contentRoot.getPath(); + File projectRoot = new File(path); + String absolutePath = projectRoot.getParentFile().getAbsolutePath(); + ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); + try { + PluginId pluginId = PluginManagerCore.getPluginByClassName(this.getClass().getName()); + if (pluginId != null) { + IdeaPluginDescriptor plugin = PluginManager.getPlugin(pluginId); + if (plugin != null) { + Thread.currentThread().setContextClassLoader(plugin.getPluginClassLoader()); + } + } + M78DoceanMongoGen m78DoceanMongoGen = new M78DoceanMongoGen(); + Result autoapp = m78DoceanMongoGen.generateAndZip(absolutePath, projectName, groupId, packageName, author, "1.0.0", null); + if (autoapp.getCode() == 0) { + return Optional.of(absolutePath + "/" + projectName); + } + } finally { + Thread.currentThread().setContextClassLoader(originalClassLoader); + } + + return Optional.empty(); + + } } + + + diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PromptUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PromptUtils.java new file mode 100644 index 000000000..688c5a90e --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PromptUtils.java @@ -0,0 +1,675 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.xiaomi.youpin.tesla.ip.bo.*; +import com.xiaomi.youpin.tesla.ip.bo.prompt.PromptParam; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.consumer.CodeConsumer; +import com.xiaomi.youpin.tesla.ip.dialog.*; +import com.xiaomi.youpin.tesla.ip.service.*; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import run.mone.ultraman.background.AthenaEditorTask; +import run.mone.ultraman.background.AthenaTask; +import run.mone.ultraman.common.Code; +import run.mone.ultraman.common.ImportCode; +import run.mone.ultraman.http.HttpClient; + +import java.lang.reflect.Type; +import java.net.URLEncoder; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2023/5/29 10:09 + */ +@Slf4j +public class PromptUtils { + + + private static final Gson gson = new Gson(); + + + public static Map getParamsFromAiProxy(String promptName, String metaStr) { + return getParamsFromAiProxy(promptName, metaStr, false); + } + + public static Map getParamsFromAiProxy(String promptName, String metaStr, boolean useSelect) { + try { + String aiRes = HttpClient.callAiProxy("params", ImmutableMap.of("name", promptName)); + Type typeOfT = new TypeToken>() { + }.getType(); + Map m = gson.fromJson(aiRes, typeOfT); + Map v = m.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), e -> "")); + if (useSelect) { + return v; + } + //使用meta中的信息 + if (StringUtils.isNotEmpty(metaStr)) { + Type to = new TypeToken>() { + }.getType(); + List promptParamList = gson.fromJson(metaStr, to); + promptParamList.forEach(it -> v.put(it.getName(), it)); + } + return v; + } catch (Throwable ex) { + log.error(ex.getMessage(), ex); + return Maps.newHashMap(); + } + } + + + /** + * 创建类(class enum) + * + * @param project + * @param modelName + * @param promptName + */ + public static void createClass(Project project, final String modelName, String promptName) { + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + List classMetas = gson.fromJson(promptInfo.getMeta(), new TypeToken>() { + }.getType()); + CreateClassMeta createClassMeta = CollectionUtils.isEmpty(classMetas) ? null : classMetas.get(0); + Editor editor = CodeService.getEditor(project); + String[] params = getParams(createClassMeta, editor); + Map v = getParamsFromAiProxy(promptName, promptInfo.getMeta(), ObjectUtils.notEqual(null, createClassMeta) && createClassMeta.isUseSelect()); + Map> mList = new HashMap<>(); + mList.put("module", ProjectUtils.listAllModules(project)); + ParamTableDialog ppt = new ParamTableDialog(ParamDialogReq.builder().title("param").build(), project, v, mList, promptInfo); + ppt.setConsumer((values) -> { + String packageStr = values.get("package").toString(); + String className = values.get("class").toString(); + String modulePath = values.get("module").toString(); + String newModelName = StringUtils.isNotBlank(modulePath) ? modulePath : getModelName(modelName, values); + + CodeService.createEmptyClass(project, newModelName, packageStr, className); + PsiClass psiClass = CodeService.getPsiClass2(project); + TextRange textRange = psiClass.getTextRange(); + CodeService.deleteTextRange(project, psiClass.getTextRange()); + Editor codeEditor = CodeService.getEditor(project); + codeEditor.getCaretModel().moveToOffset(textRange.getStartOffset()); + Map pm = values.entrySet().stream().collect(Collectors.toMap(en -> en.getKey(), en -> en.getValue().toString())); + CodeService.generateCodeWithAi3(project, promptName, params, pm, (p, code) -> CodeService.writeCode2(p, codeEditor, code)); + }); + ppt.show(); + } + + private static String getModelName(String modelName, Map values) { + if (StringUtils.isEmpty(modelName)) { + modelName = values.getOrDefault("module", "").toString(); + } + return modelName; + } + + @Nullable + private static String[] getParams(CreateClassMeta createClassMeta, Editor editor) { + String[] params = null; + if (ObjectUtils.notEqual(null, createClassMeta) && createClassMeta.isUseSelect()) { + params = new String[]{EditorUtils.getSelectContent(editor)}; + } + return params; + } + + + public static void createClass2(Project project, String promptName, String showDialog, Map param) { + String isShowDialog = StringUtils.isEmpty(showDialog) ? "true" : showDialog; + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + Map v = getParamsFromAiProxy(promptName, promptInfo.getMeta()); + if ("true".equals(isShowDialog)) { + String url = buildDialogUrl(project, v, promptInfo); + ChromeDialog chromeDialog = new ChromeDialog(url, project); + chromeDialog.show(); + return; + } + + String packageStr = param.get("package").toString(); + String className = param.get("class").toString(); + String modelName = param.get("modelName").toString(); + + CodeService.createEmptyClass(project, modelName, packageStr, className); + + PsiClass psiClass = CodeService.getPsiClass2(project); + TextRange textRange = psiClass.getTextRange(); + CodeService.deleteTextRange(project, psiClass.getTextRange()); + Editor codeEditor = CodeService.getEditor(project); + codeEditor.getCaretModel().moveToOffset(textRange.getStartOffset()); + + Map pm = param.entrySet().stream().collect(Collectors.toMap(en -> en.getKey(), en -> en.getValue().toString())); + CodeService.generateCodeWithAi3(project, promptName, new String[]{}, pm, (p, code) -> CodeService.writeCode2(p, codeEditor, code)); + + } + + + public static void createClass3(Project project, String promptName, Map param) { + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + + String packageStr = param.get("package").toString(); + String className = param.get("class").toString(); + String modelName = param.get("modelName").toString(); + + CodeService.createEmptyClass(project, modelName, packageStr, className); + + PsiClass psiClass = CodeService.getPsiClass2(project); + TextRange textRange = psiClass.getTextRange(); + CodeService.deleteTextRange(project, psiClass.getTextRange()); + Editor codeEditor = CodeService.getEditor(project); + codeEditor.getCaretModel().moveToOffset(textRange.getStartOffset()); + + } + + + /** + * $$->隐藏 + * $@$->选择框 + * + * @param project + * @param param + * @param promptInfo + * @return + */ + private static String buildDialogUrl(Project project, Map param, PromptInfo promptInfo) { + if (!param.containsKey("model")) { + param.put("$@$model", ProjectUtils.listAllModules(project)); + } + if (!param.containsKey("package")) { + param.put("package", ""); + } + if (param.containsKey("class")) { + param.put("class", ""); + } + param.put("$$showDialog", "false"); + param.put("$$prompt", promptInfo.getPromptName()); + param.put("$$desc", promptInfo.getDesc()); + return ConfigUtils.getConfig().getChatServer() + "/code-form" + "?param=" + URLEncoder.encode(gson.toJson(param)); + } + + /** + * 给方法添加注释 + * + * @param req + */ + public static void addComment(GenerateCodeReq req) { + Project project = req.getProject(); + PsiMethod method = CodeService.getMethod(project); + Editor editor = CodeService.getEditor(project); + if (null == method) { + HintUtils.show(editor, Message.selectMethodMsg, true); + return; + } + String c = method.getText(); + Map map = Maps.newHashMap(); + map.put("code", c); + + AthenaTask task = new AthenaTask(req.getProject(), "Athena", req.getPromptName(), "", map); + task.setType("method_comment"); + PromptContext context = new PromptContext(); + context.setEditor(editor); + task.setPromptContext(context); + task.setReq(req); + AthenaTask.start(task); + } + + + /** + * 修改class + * + * @param project + * @param promptName + */ + public static void modifyClass(Project project, String promptName) { + PsiClass psiClass = CodeService.getPsiClass2(project); + String codeStr = psiClass.getText(); + CodeService.deletePsiClass(project, psiClass); + Editor codeEditor = CodeService.getEditor(project); + CodeService.generateCodeWithAi2(project, promptName, new String[]{codeStr}, (p, code) -> CodeService.writeCode2(p, codeEditor, code)); + } + + + /** + * 创建一个文件 + * + * @param req + */ + public static void createFile(String promptName, String fileName, GenerateCodeReq req) { + fileName = req.getPromptInfo().getLabels().getOrDefault("fileName", "athena_"); + String scope = req.getPromptInfo().getLabels().getOrDefault("scope", "method"); + String codeStr = ""; + if (scope.equals("method")) { + codeStr = CodeService.getMethod(req.getProject()).getText(); + } else if (scope.equals("class")) { + PsiClass psiClass = CodeService.getPsiClass(req.getProject()); + codeStr = psiClass.getText(); + fileName = fileName + psiClass.getName(); + } else if (scope.equals("select")) { + codeStr = CodeService.getSelectedText(CodeService.getEditor(req.getProject())); + } + final String c = codeStr; + TextService.writeContent(req.getProject(), fileName + ".md", req.getModule().getName(), () -> { + Editor editor = CodeService.getEditor(req.getProject()); + Map m = Maps.newHashMap(); + m.put("code", c); + CodeService.generateCodeWithAi3(req.getProject(), promptName, new String[]{req.getMeta()}, m, (p, code) -> CodeService.writeCode4(p, editor, code, false)); + }); + } + + /** + * 修改一个类,会清空编辑区的所有内容 + * + * @param req + */ + public static void updateClass(GenerateCodeReq req) { + PsiClass psiClass = CodeService.getPsiClass(req.getProject()); + String classCode = psiClass.getText(); + TextRange textRange = psiClass.getTextRange(); + CodeService.deleteTextRange(req.getProject(), textRange); + Editor editor = CodeService.getEditor(req.getProject()); + CodeService.generateCodeWithAi2(req.getProject(), req.getPromptName(), new String[]{classCode}, (p, code) -> CodeService.writeCode2(p, editor, code)); + } + + public static void modifyMethod(GenerateCodeReq req) { + Editor editor = CodeService.getEditor(req.getProject()); + if (null == editor) { + return; + } + //修改方法名 + if (LabelUtils.isOpen(req.getProject(), req.getPromptInfo(), "modify_method_name") || LabelUtils.isOpen(req.getProject(), req.getPromptInfo(), "modify_method_param_name")) { + Map m = new HashMap<>(); + + PsiMethod method = CodeService.getMethod(req.getProject()); + if (null == method) { + HintUtils.show(editor, com.xiaomi.youpin.tesla.ip.bo.Message.selectMethodMsg, true); + return; + } + m.put("code", method.getText()); + m.put("paramName", req.getParam().getOrDefault("paramName", "")); + AthenaEditorTask task = new AthenaEditorTask(req, "Athena", m, new MessageConsumer() { + private StringBuilder sb = new StringBuilder(); + + @Override + public void onEvent(AiMessage message) { + sb.append(message.getText()); + } + + @Override + public void end(AiMessage message) { + if (LabelUtils.isOpen(req.getProject(), req.getPromptInfo(), "modify_method_name")) { + PsiMethodUtils.renameMethod(req.getProject(), method, sb.toString()); + } else { + PsiMethodUtils.renameParameter(req.getProject(), (PsiParameter) req.getObjMap().get("parameter"), sb.toString()); + } + } + }); + AthenaEditorTask.start(task); + } + } + + /** + * 给一个方法添加逐行注释,或者代码 + * + * @param promptName + * @param req + */ + public static void lineByLineCommentOrCode(String promptName, GenerateCodeReq req) { + Editor editor = null; + try { + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + Map map = promptInfo.getLabels(); + editor = req.getEditor(); + addImportList(req.getProject(), map); + String codeStr = getCode(req, map); + codeStr = filterAnnoCode(codeStr, promptInfo); + PsiDocumentManager documentManager = PsiDocumentManager.getInstance(req.getProject()); + @Nullable PsiFile psiFile = documentManager.getPsiFile(editor.getDocument()); + Code code = new Code(); + code.setEditor(editor); + code.setPromptInfo(promptInfo); + code.setDocument(editor.getDocument()); + code.setProject(req.getProject()); + code.setPsiFile(psiFile); + AthenaEditorTask.start(new AthenaEditorTask(req, "Athena", codeStr, ImmutableMap.of("code", codeStr), new CodeConsumer(editor, req) { + @Override + public void onEvent(AiMessage message) { + code.append(message.getText()); + } + })); + } catch (Throwable ex) { + HintUtils.show(editor, ex.getMessage(), true); + } + } + + private static String filterAnnoCode(String codeStr, PromptInfo promptInfo) { + String str = promptInfo.getLabels().getOrDefault("delete", "").trim(); + if (StringUtils.isEmpty(str)) { + return codeStr; + } + String[] skipArray = str.split(","); + if (skipArray.length > 0) { + return codeStr.lines().map(it -> { + boolean has = Arrays.stream(skipArray).filter(it2 -> it.contains(it2)).findAny().isPresent(); + if (has) { + int begin = it.indexOf("@"); + return it.substring(0, begin); + } + return it; + }).collect(Collectors.joining("\n")); + } + return codeStr; + } + + private static void addImportList(Project project, Map map) { + if (map.containsKey("import")) { + String str = map.get("import"); + Type typeOfT = new TypeToken>() { + }.getType(); + List importList = gson.fromJson(str, typeOfT); + CodeService.addImport(project, importList); + } + } + + public static List getImportList(PromptInfo promptInfo) { + Map labels = promptInfo.getLabels(); + if (null != labels && labels.containsKey("import")) { + String str = labels.get("import"); + Type typeOfT = new TypeToken>() { + }.getType(); + List importList = gson.fromJson(str, typeOfT); + return importList; + } + return Lists.newArrayList(); + } + + /** + * 根据lable里的scope获取代码,有可能是method,也有可能是class + * + * @param req + * @param map + * @return + */ + @NotNull + private static String getCode(GenerateCodeReq req, Map map) { + String codeStr = ""; + String scope = getScope(req, map); + if (scope.equals("class")) { + codeStr = CodeService.getClassAndLineNumbers(CodeService.getPsiClass(req.getProject())); + } else { + PsiMethod method = CodeService.getMethod(req.getProject()); + if (null == method) { + throw new RuntimeException(Message.selectMethodMsg); + } + codeStr = CodeService.getMethodAndLineNumbers(method); + } + return codeStr; + } + + @NotNull + private static String getScope(GenerateCodeReq req, Map map) { + String scope = "method"; + if (null != map && map.containsKey("scope")) { + scope = map.getOrDefault("scope", "nearby"); + } + //就近选择(离method近,就是method,离class近就是class) + if (scope.equals("nearby")) { + PsiMethod method = CodeService.getMethod(req.getProject()); + if (null != method) { + scope = "method"; + } else { + scope = "class"; + } + } + return scope; + } + + + private static Pair getPackageAndClass(DialogResult result) { + String className = result.getData().get("class"); + String[] strs = className.split("\\."); + String packageStr = Arrays.stream(strs).limit(strs.length - 1).collect(Collectors.joining(".")); + return Pair.of(packageStr, strs[strs.length - 1]); + + } + + private static DialogResult showDialog(Project project, Module module, String data) { + DialogReq dialogReq = gson.fromJson(data, DialogReq.class); + dialogReq.setModule(module); + SelectClassAndMethodDialog dialog = new SelectClassAndMethodDialog(project, dialogReq); + dialog.show(); + int exitCode = dialog.getExitCode(); + if (exitCode != DialogWrapper.OK_EXIT_CODE) { + return null; + } + DialogResult result = dialog.getResult(); + return result; + } + + /** + * 生成接口 + * + * @param req + */ + public static void generateInterface(GenerateCodeReq req) { + Project project = req.getProject(); + String ps = req.getClassCode(); + Map map = new HashMap<>(); + map.put("code", ps); + String qualifiedName = req.getQualifiedName(); + String packageName = qualifiedName.substring(0, qualifiedName.lastIndexOf('.')); + + ImportCode code = CodeService.createClassAndAddEmptyLine(project, req.getModule().getName(), packageName, req.getClassName(), "Interface", false, true); + + AthenaEditorTask.start(new AthenaEditorTask(req, "Athena", ps, map, new MessageConsumer() { + @Override + public void onEvent(AiMessage message) { + code.append(message.getText()); + } + })); + + } + + + public static void generateTestMethod(GenerateCodeReq req) { + Project project = req.getProject(); + if (StringUtils.isEmpty(req.getMethodCode())) { + HintUtils.show(req.getEditor(), Message.selectMethodMsg, true); + return; + } + String methodCode = req.getMethodCode(); + String qualifiedName = req.getQualifiedName(); + String packageName = qualifiedName.substring(0, qualifiedName.lastIndexOf('.')); + + ImportCode code = CodeService.createClassAndAddEmptyLine(project, req.getModule().getName(), packageName, req.getClassName(), "Test", true, false); + + Map map = new HashMap<>(); + map.put("code", "public class" + req.getClassName() + "{" + methodCode + " \n}"); + AthenaEditorTask.start(new AthenaEditorTask(req, "Athena", methodCode, map, new MessageConsumer() { + @Override + public void onEvent(AiMessage message) { + code.append(message.getText()); + } + })); + + + } + + /** + * 操作之前这里有选择(选择类名或者方法名) + * 更底层的机制是根据一段代码,生成一个方法或者替代一个方法 + *

+ * 用来生成测试方法 + */ + public static void select(GenerateCodeReq req, Project project, Module module, PromptInfo promptInfo) { + String codeClassName = CodeService.getPsiClass(project).getQualifiedName(); + PsiClass pc = CodeService.getPsiClass(project); + boolean springClass = LabelUtils.open("check_spring") && SpringUtils.isSpringClass(pc); + + PsiMethod pm = CodeService.getMethod(project); + if (null == pm) { + HintUtils.show(CodeService.getEditor(project), Message.selectMethodMsg, true); + return; + } + String methodCode = pm.getText(); + + //选择类和方法 + DialogResult result = showDialog(project, module, promptInfo.getMeta()); + + if (null == result) { + return; + } + String methodName = result.getData().get("method"); + String className = result.getData().get("class"); + + //创建新类 + if (result.getData().get("new_class").equals("true")) { + Pair pair = getPackageAndClass(result); + String addAnno = promptInfo.getLabels().getOrDefault("add_anno", ""); + List annoList = gson.fromJson(addAnno, new TypeToken>() { + }.getType()); + CodeService.createEmptyClass(project, module.getName(), pair.getKey(), pair.getValue(), true, annoList); + } + + PsiClass psiClass = CodeService.openJavaClass(project, className); + + String testClassCode = psiClass.getText(); + + Editor editor = CodeService.getEditor(project); + + Map map = new HashMap<>(); + + //spring 单元测试,需要把字段注入 + if (springClass) { + String serviceName = pc.getQualifiedName(); + String shortServiceName = pc.getNameIdentifier().getText(); + String junitVersion = ImportUtils.junitVersion(psiClass); + PromptService.addImports(req, project, serviceName, null, editor, true, true, junitVersion); + PromptService.addFields(project, serviceName, shortServiceName, psiClass, editor); + //spring 单元测试带上之前的测试代码 + map.put("context", editor.getDocument().getText()); + } else { + map.put("context", ""); + } + + //创建新方法,还是覆盖老的方法(并且光标移动到合理的位置) + if (methodName.equals("New")) { + PsiMethod @NotNull [] methods = psiClass.getMethods(); + int offset = 0; + if (0 == methods.length) { + offset = psiClass.getTextRange().getEndOffset() - 3; + } else { + PsiMethod psiMethod = methods[methods.length - 1]; + offset = psiMethod.getTextRange().getEndOffset(); + } + editor.getCaretModel().moveToOffset(offset); + CodeService.writeCode2(project, editor, "\n"); + } else { + PsiMethod psiMethod = CodeService.getMethod(psiClass, methodName); + CodeService.deleteMethod(project, psiMethod); + } + + generateUnitTest(project, methodCode, codeClassName, map, testClassCode, editor); + } + + /** + * 打开单元测试类 + * 设置偏移量,如果方法数组长度为 0 则进行特定计算,否则根据最后一个方法的结束偏移量计算 + */ + public static String openUnitTestClass(Project project, String className) { + PsiClass psiClass = CodeService.openJavaClass(project, className); + String testClassCode = psiClass.getText(); + Editor editor = CodeService.getEditor(project); + PsiMethod @NotNull [] methods = psiClass.getMethods(); + int offset = 0; + if (0 == methods.length) { + offset = psiClass.getTextRange().getEndOffset() - 3; + } else { + PsiMethod psiMethod = methods[methods.length - 1]; + offset = psiMethod.getTextRange().getEndOffset(); + } + editor.getCaretModel().moveToOffset(offset); + CodeService.writeCode2(project, editor, "\n"); + return testClassCode; + } + + //生成单元测试代码 + public static void generateUnitTest(Project project, String methodCode, String codeClassName, Map map, String testClassCode, Editor editor) { + generateUnitTest(project, methodCode, codeClassName, map, testClassCode, editor, null); + } + + public static void generateUnitTest(Project project, String methodCode, String codeClassName, Map map, String testClassCode, Editor editor, CountDownLatch latch) { + //生成测试方法的时候,让他能推理出来类名 + methodCode = "public class " + codeClassName + " {\n" + methodCode + "\n}"; + map.put("code", methodCode); + //单元测试那个类的内容 + map.put("testClassCode", testClassCode); + invokePrompt(project, Const.GENERATE_UNIT_TEST, map, editor, latch); + } + + + private static void invokePrompt(Project project, String promptName, Map param, Editor editor) { + invokePrompt(project, promptName, param, editor, null); + } + + private static void invokePrompt(Project project, String promptName, Map param, Editor editor, CountDownLatch latch) { + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + PromptType promptType = Prompt.getPromptType(promptInfo); + //直接使用bot + PromptService.dynamicInvoke(GenerateCodeReq.builder() + .project(project) + .promptType(promptType) + .promptName(promptName) + .promptInfo(promptInfo) + .countDownLatch(latch) + .param(param) + .editor(editor) + .build()); + } + + public static void checkPomVersion(GenerateCodeReq req) { + Editor editor = CodeService.getEditor(req.getProject()); + PromptInfo promptInfo = Prompt.getPromptInfo(req.getPromptName()); + Map lables = promptInfo.getLabels(); + Dependency dependency = gson.fromJson(lables.get("version"), Dependency.class); + Pair checkRes = XmlService.checkPomVersion(req.getProject(), dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); + HintUtils.show(editor, checkRes.getKey() == 0 ? Result.success(checkRes.getValue()) : Result.fail(-1, checkRes.getValue())); + } + + public static void generateAnnoForBootStrap(String promptName, Project project) { + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + PsiClass applicationBootStrapClass = PsiClassUtils.findApplicationRunClass(project); + if (applicationBootStrapClass == null) { + HintUtils.show(CodeService.getEditor(project), Result.fail(-1, "没有找到启动类!")); + return; + } + Map labels = promptInfo.getLabels(); + String annos = labels.get("anno"); + List annoList = gson.fromJson(annos, new TypeToken>() { + }.getType()); + Editor editor = EditorUtils.getEditorFromPsiClass(project, applicationBootStrapClass); + CodeService.addImport(project, editor, gson.fromJson(labels.get("import"), new TypeToken>() { + }.getType())); + CodeService.addClassAnno(project, applicationBootStrapClass, annoList); + } + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PsiClassFixer.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PsiClassFixer.java new file mode 100644 index 000000000..09e4db982 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PsiClassFixer.java @@ -0,0 +1,204 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInspection.InspectionManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.List; + +/** + * goodjava@qq.com + * minzai + */ +public class PsiClassFixer { + + /** + * 修复类中引用的不存在方法 + * + * @param psiClass 要修复的类 + * @param project 当前项目 + */ + public static void fixUndefinedMethods(PsiClass psiClass, Project project) { + // 在写操作中执行修复 + WriteCommandAction.runWriteCommandAction(project, () -> { + for (PsiMethod method : psiClass.getMethods()) { + PsiCodeBlock body = method.getBody(); + if (body != null) { + body.accept(new JavaRecursiveElementVisitor() { + @Override + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + super.visitMethodCallExpression(expression); + + // 获取方法调用表达式 + PsiReferenceExpression methodExpression = expression.getMethodExpression(); + if (methodExpression != null) { + // 解析方法引用 + PsiElement referencedMethod = methodExpression.resolve(); + + if (referencedMethod == null) { + String methodName = methodExpression.getReferenceName(); + + if (methodName != null) { + Pair isReferencedClassPair = isReferencedClass(methodExpression); + if (isReferencedClassPair.getKey()){ + // 添加空方法到当前类 + addEmptyMethod(psiClass, methodName, expression); + } else { + // 添加空方法到外部类 + addEmptyMethod(isReferencedClassPair.getValue(), methodName, expression); + } + } + } + } + } + }); + } + } + }); + } + + /** + * 查找引用的外部类 + * + * @param methodExpression 方法引用表达式 + * @return 引用的外部类 + */ + private static Pair isReferencedClass(PsiReferenceExpression methodExpression) { + boolean isCurrentClassFlag = false; + PsiClass referencedClass = null; + + // 获取方法调用的限定表达式,例如 "this.method()" 或 "SomeClass.method()" + PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); + + if (qualifierExpression instanceof PsiThisExpression || qualifierExpression == null) { + // 如果限定表达式是 "this" 或者没有限定表达式,那么它是当前类的方法 + isCurrentClassFlag = true; + } else if (qualifierExpression instanceof PsiReferenceExpression) { + // 如果限定表达式是引用表达式,可能是外部类的方法 + PsiElement qualifier = ((PsiReferenceExpression) qualifierExpression).resolve(); + if (qualifier instanceof PsiClass) { + // 如果解析的限定符是一个类,那么它是外部类的方法 + referencedClass = (PsiClass) qualifier; + } + } + return Pair.of(isCurrentClassFlag, referencedClass); + } + + /** + * 添加空方法到指定类中 + * + * @param psiClass 指定类 + * @param methodName 方法名 + * @param expression 方法调用表达式(用于获取参数和返回类型) + */ + private static void addEmptyMethod(PsiClass psiClass, String methodName, PsiMethodCallExpression expression) { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiClass.getProject()); + + // 获取方法参数和返回类型 + PsiExpressionList argumentList = expression.getArgumentList(); + PsiType returnType = getMethodCallReturnType(expression); + + // 构建方法签名 + StringBuilder methodSignature = new StringBuilder("public static "); + if (returnType != null) { + methodSignature.append(returnType.getCanonicalText()).append(" "); + } else { + methodSignature.append("void "); + } + methodSignature.append(methodName).append("("); + + if (argumentList != null) { + PsiExpression[] arguments = argumentList.getExpressions(); + for (int i = 0; i < arguments.length; i++) { + PsiExpression argument = arguments[i]; + methodSignature.append(argument.getType().getCanonicalText()).append(" arg").append(i); + if (i < arguments.length - 1) { + methodSignature.append(", "); + } + } + } + // 创建空方法并添加返回语句 + String returnStatement = getReturnStatement(returnType); + methodSignature.append(") { " + returnStatement + " }"); + + // 创建新的方法并添加到类中 + PsiMethod newMethod = elementFactory.createMethodFromText(methodSignature.toString(), psiClass); + psiClass.add(newMethod); + } + + + public static void a(Project project) { + InspectionManager inspectionManager = InspectionManager.getInstance(project); + DaemonCodeAnalyzer daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(project); + } + + public static void addFields0(PsiClass psiClass) { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiClass.getProject()); + PsiField ageField = elementFactory.createField("age", PsiTypes.intType()); + PsiField nameField = elementFactory.createField("name", PsiType.getJavaLangString(psiClass.getManager(), psiClass.getResolveScope())); + + WriteCommandAction.runWriteCommandAction(psiClass.getProject(), () -> { + // 添加字段前检查是否已存在同名字段 + if (psiClass.findFieldByName("age", false) == null) { + psiClass.add(ageField); + } + if (psiClass.findFieldByName("name", false) == null) { + psiClass.add(nameField); + } + }); + } + + public static void addFields(PsiClass psiClass, List fieldList) { + WriteCommandAction.runWriteCommandAction(psiClass.getProject(), () -> { + fieldList.forEach(it -> psiClass.add(it)); + }); + + } + private static PsiType getMethodCallReturnType(PsiMethodCallExpression expression) { + PsiElement parent = expression.getParent(); + if (parent instanceof PsiAssignmentExpression) { + PsiAssignmentExpression assignment = (PsiAssignmentExpression) parent; + PsiExpression lExpression = assignment.getLExpression(); + if (lExpression instanceof PsiReferenceExpression) { + PsiElement resolved = ((PsiReferenceExpression) lExpression).resolve(); + if (resolved instanceof PsiVariable) { + return ((PsiVariable) resolved).getType(); + } + } + } else if (parent instanceof PsiVariable) { + return ((PsiVariable) parent).getType(); + } else if (parent instanceof PsiReturnStatement) { + PsiMethod containingMethod = PsiTreeUtil.getParentOfType(expression, PsiMethod.class); + if (containingMethod != null) { + return containingMethod.getReturnType(); + } + } + // 其他情况,可能需要更复杂的逻辑来确定返回类型 + return null; + } + + /** + * 获取返回语句 + * + * @param returnType 返回类型 + * @return 返回语句 + */ + private static String getReturnStatement(PsiType returnType) { + if (PsiType.VOID.equals(returnType)) { + return ""; + } else if (PsiType.BOOLEAN.equals(returnType)) { + return "return false;"; + } else if (PsiType.INT.equals(returnType) || PsiType.LONG.equals(returnType) || PsiType.FLOAT.equals(returnType) || PsiType.DOUBLE.equals(returnType)) { + return "return 0;"; + } else if (PsiType.CHAR.equals(returnType)) { + return "return '\0';"; + } else { + return "return null;"; + } + } +} + diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/PsiClassUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PsiClassUtils.java similarity index 62% rename from athena-all/src/main/java/run/mone/m78/ip/util/PsiClassUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PsiClassUtils.java index 9085f1cec..57b091ee4 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/PsiClassUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PsiClassUtils.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.google.common.collect.ImmutableList; import com.intellij.openapi.command.WriteCommandAction; @@ -9,21 +9,25 @@ import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiShortNamesCache; -import run.mone.m78.ip.bo.AddMethodConfig; -import run.mone.m78.ip.bo.ParamInfo; -import run.mone.m78.ip.common.JavaClassUtils; -import run.mone.m78.ip.service.CodeService; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.InheritanceUtil; +import com.xiaomi.youpin.tesla.ip.bo.AddMethodConfig; +import com.xiaomi.youpin.tesla.ip.bo.Message; +import com.xiaomi.youpin.tesla.ip.bo.ParamInfo; +import com.xiaomi.youpin.tesla.ip.common.JavaClassUtils; +import com.xiaomi.youpin.tesla.ip.service.CodeService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import run.mone.ultraman.bo.AthenaClassInfo; import run.mone.ultraman.service.AthenaCodeService; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; /** @@ -58,7 +62,6 @@ public static PsiClass findClassByName(Project project, String className) { return psiClass; } - /** * 添加字段 * 如果里边有同名字段则不添加 @@ -147,7 +150,6 @@ public static PsiClass findApplicationRunClass(Project project) { return null; } - public static PsiDirectory getSourceDirectory(Project project, String moduleName, boolean testPath) { return getSourceDirectory(project, moduleName, testPath, "java"); } @@ -165,27 +167,67 @@ public static void createEmptyClass(Project project, String moduleName, String p createEmptyClass(project, moduleName, packageName, className, testPath, false, null, isInterface); } - public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath, boolean openClass, List annoList, boolean isInterface) { - + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiDirectory psiDirectory = getSourceDirectory(project, moduleName, testPath); + if (null == psiDirectory) { + HintUtils.show(CodeService.getEditor(project), Message.cannotFindTestDirectory, true); + return; + } + String[] packageParts = packageName.split("\\."); + for (String packagePart : packageParts) { + PsiDirectory subDirectory = psiDirectory.findSubdirectory(packagePart); + if (subDirectory == null) { + subDirectory = psiDirectory.createSubdirectory(packagePart); + } + psiDirectory = subDirectory; + } + PsiDirectory tmp = psiDirectory; + String classText = isInterface ? buildEmptyInterfaceInfo(className) : buildEmptyClassInfo(project, className, testPath, annoList); + PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(project); + PsiFile psiFile = psiFileFactory.createFileFromText(className + ".java", classText); + tmp.add(psiFile.getContainingFile()); + if (openClass) { + JavaClassUtils.openClass(project, className); + } + }); } //创建一个类,并打开 public static void createClass(Project project, String packageStr, String className, String code) { + createClass(project, packageStr, className, code, true); + } + + public static void createClass(Project project, String packageStr, String className, String code, boolean format) { WriteCommandAction.runWriteCommandAction(project, () -> { PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(project); PsiFile psiFile = psiFileFactory.createFileFromText(className + ".java", code); PsiDirectory directory = getDirectoryFromPackage(project, packageStr); directory.add(psiFile); - //打开这个类 - JavaClassUtils.openClass(project, className); - //格式化代码 - CodeService.formatCode(project); + if (format) { + //打开这个类 + JavaClassUtils.openClass(project, className); + //格式化代码 + CodeService.formatCode(project); + } + }); + } + + public static void createClass(Project project, String className, String code, boolean format, PsiDirectory directory) { + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiFileFactory psiFileFactory = PsiFileFactory.getInstance(project); + PsiFile psiFile = psiFileFactory.createFileFromText(className + ".java", code); + directory.add(psiFile); + if (format) { + //打开这个类 + JavaClassUtils.openClass(project, className); + //格式化代码 + CodeService.formatCode(project); + } }); } public static PsiDirectory getDirectoryFromPackage(Project project, String packagePath) { - PsiManager psiManager = PsiManager.getInstance(project); JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project); PsiPackage psiPackage = javaPsiFacade.findPackage(packagePath); if (psiPackage != null) { @@ -197,7 +239,6 @@ public static PsiDirectory getDirectoryFromPackage(Project project, String packa return null; } - private static String buildEmptyClassInfo(Project project, String className, boolean testPath, List annoList) { String classText = testPath ? String.format("public class %s{\n\n}", className) @@ -242,22 +283,51 @@ public static PsiDirectory getSourceDirectory(Project project, String moduleName return null; } - public static PsiDirectory getSourceDirectory(Project project, String moduleName) { return getSourceDirectory(project, moduleName, "/src/main/java"); } + public static PsiDirectory getSourceDirectoryWithModule(Project project, String moduleName) { + return getSourceDirectory(project, moduleName, "/src/main/java", false, false); + } + + public static PsiDirectory getTestSourceDirectory(Project project, String moduleName) { + return getSourceDirectory(project, moduleName, "/src/test/java", true, false); + } + + public static PsiDirectory getSourceDirectory(Project project, String moduleName, String containsPath) { + return getSourceDirectory(project, moduleName, containsPath, false, true); + } + + public static PsiDirectory createPackageDirectories(PsiDirectory directory, String packageName) { + String[] names = packageName.split("\\."); + for (String name : names) { + PsiDirectory subdirectory = directory.findSubdirectory(name); + if (subdirectory == null) { + directory = directory.createSubdirectory(name); + } else { + directory = subdirectory; + } + } + return directory; + } + + public static PsiDirectory getSourceDirectory(Project project, String moduleName, String containsPath, boolean includingTests, boolean getParent) { Module[] modules = ModuleManager.getInstance(project).getModules(); for (Module module : modules) { ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); if (!module.getName().equals(moduleName)) { continue; } - for (VirtualFile sourceFolder : moduleRootManager.getSourceRoots(false)) { + for (VirtualFile sourceFolder : moduleRootManager.getSourceRoots(includingTests)) { //包含/test/目录才是测试代码路径 if (sourceFolder.getPath().contains(containsPath)) { - return PsiManager.getInstance(project).findDirectory(sourceFolder).getParent(); + PsiDirectory res = PsiManager.getInstance(project).findDirectory(sourceFolder); + if (getParent) { + return res.getParent(); + } + return res; } } } @@ -281,8 +351,26 @@ public static PsiDirectory getDirectory(Project project, String moduleName, Stri return null; } - public static PsiDirectory getSourceDirectory(Project project, boolean testPath, String packagePath) { + Module[] modules = ModuleManager.getInstance(project).getModules(); + for (Module module : modules) { + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + for (VirtualFile sourceFolder : moduleRootManager.getSourceRoots(testPath)) { + //包含/test/目录才是测试代码路径 + if (testPath && !sourceFolder.getPath().contains("/src/test/java")) { + continue; + } + + if (!module.getName().contains("demo-server")) { + continue; + } + + if (sourceFolder.getName().equals("java")) { + sourceFolder = sourceFolder.findFileByRelativePath(packagePath.replace('.', '/')); + return PsiManager.getInstance(project).findDirectory(sourceFolder); + } + } + } return null; } @@ -292,17 +380,26 @@ public static Module getModule(Project project, PsiClass psiClass) { return module; } - private static List list = ImmutableList.of("javax.annotation.Resource", "jakarta.annotation.Resource" - , "org.springframework.beans.factory.annotation.Autowired", "org.apache.dubbo.config.annotation.Reference" - , "org.apache.dubbo.config.annotation.DubboReference" + //需要分析的引入类 + private static List list = ImmutableList.of("javax.annotation.Resource", + "jakarta.annotation.Resource", + "org.springframework.beans.factory.annotation.Autowired", + "org.apache.dubbo.config.annotation.Reference", + "org.apache.dubbo.config.annotation.DubboReference" ); - public static List findFieldsWithResourceAnnotation(@NotNull PsiClass psiClass) { - return Arrays.stream(psiClass.getFields()).filter(it -> hasAnno(it, list)).collect(Collectors.toList()); + @Nullable PsiClass superClass = psiClass.getSuperClass(); + List superClassFields = new ArrayList<>(); + //父类里有,也会被拉取出来 + if (null != superClass) { + superClassFields.addAll(Arrays.stream(superClass.getFields()).filter(it -> hasAnno(it, list)).collect(Collectors.toList())); + } + List fields = Arrays.stream(psiClass.getFields()).filter(it -> hasAnno(it, list)).collect(Collectors.toList()); + fields.addAll(superClassFields); + return fields; } - private static boolean hasAnno(PsiField field, List annoList) { if (null == field || null == annoList) { return false; @@ -340,7 +437,6 @@ public static String getClassText(Project project, String text) { return ""; } - public static String getInterfaceText(Project project, PsiClass originalClass) { //直接先分析下代码,如果加了@Data注解,则直接自己分析了 try { @@ -389,5 +485,88 @@ public static String getInterfaceText(Project project, PsiClass originalClass) { } + /** + * 查找指定类继承的非私有非静态方法集合. + * 遍历给定类的所有父类,忽略Object类,筛选出所有非私有非静态方法. + * 如果父类是接口,则只考虑默认方法. + * + * @param psiClass 需要查找方法的类 + * @return 继承的非私有非静态方法集合 + */ + public static Set findInheritedNonPrivateNonStaticMethods(PsiClass psiClass) { + Set inheritedMethods = new HashSet<>(); + LinkedHashSet superClasses = InheritanceUtil.getSuperClasses(psiClass); + for (PsiClass superClass : superClasses) { + if (superClass.getName().equals("Object")) { + continue; + } + // 获取当前父类的所有方法 + PsiMethod[] methods = superClass.getMethods(); + for (PsiMethod method : methods) { + if (superClass.isInterface() && !method.hasModifierProperty(PsiModifier.DEFAULT)) { + continue; + } + // 检查方法是否是继承来的 + if (!method.hasModifierProperty(PsiModifier.PRIVATE) && !method.hasModifierProperty(PsiModifier.STATIC)) { + // 如果方法不是 private 或 static,那么它可能是被继承的 + inheritedMethods.add(method); + } + } + } + return inheritedMethods; + } + + public static String generateMethodSignature(PsiMethod psiMethod) { + // 获取方法的访问修饰符(public, private, 等等) + if (psiMethod.isConstructor() || psiMethod.getReturnType() == null) { + return ""; + } + String modifier = psiMethod.getModifierList().getText(); + String returnType = psiMethod.getReturnType().getPresentableText(); + String methodName = psiMethod.getName(); + PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); + StringBuilder paramsBuilder = new StringBuilder(); + // 获取方法的文档注释(如果存在) + PsiDocComment docComment = psiMethod.getDocComment(); + StringBuilder commentBuilder = new StringBuilder(); + // 如果存在文档注释,则获取注释的文本并添加到commentBuilder + if (docComment != null) { + commentBuilder.append(docComment.getText()); + } + + String comment = getSingleLineCommentAboveMethod(psiMethod); + if (StringUtils.isNotEmpty(comment)) { + commentBuilder.append(comment); + } + + for (PsiParameter param : parameters) { + if (paramsBuilder.length() > 0) { + paramsBuilder.append(", "); + } + paramsBuilder.append(param.getType().getPresentableText()).append(" ").append(param.getName()); + } + String methodDefinition = modifier + " " + returnType + " " + methodName + "(" + paramsBuilder.toString() + ")"; + return commentBuilder + "\n" + methodDefinition; + } + + /** + * 获取给定方法上方的单行注释文本. + * 遍历方法节点的前一个兄弟节点,直到找到单行注释或者不再有前一个兄弟节点为止. + * 如果找到单行注释,则返回该注释的文本内容;否则返回null. + */ + public static String getSingleLineCommentAboveMethod(PsiMethod psiMethod) { + for (PsiElement child : psiMethod.getChildren()) { + if (child instanceof PsiComment) { + PsiComment comment = (PsiComment) child; + IElementType type = comment.getTokenType(); + if (JavaTokenType.END_OF_LINE_COMMENT.equals(type)) { + return comment.getText(); + } + } else { + break; + } + } + return null; // No single line comment found + } } diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/PsiFieldUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PsiFieldUtils.java similarity index 91% rename from athena-all/src/main/java/run/mone/m78/ip/util/PsiFieldUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PsiFieldUtils.java index 8420fd73a..923b266f1 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/PsiFieldUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/PsiFieldUtils.java @@ -1,13 +1,13 @@ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.intellij.openapi.project.Project; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElementFactory; import com.intellij.psi.PsiField; -import run.mone.m78.ip.bo.AnnoInfo; -import run.mone.m78.ip.bo.AnnoMember; -import run.mone.m78.ip.bo.FieldInfo; +import com.xiaomi.youpin.tesla.ip.bo.AnnoInfo; +import com.xiaomi.youpin.tesla.ip.bo.AnnoMember; +import com.xiaomi.youpin.tesla.ip.bo.FieldInfo; import java.util.Arrays; import java.util.List; diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/ResourceUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ResourceUtils.java similarity index 54% rename from athena-all/src/main/java/run/mone/m78/ip/util/ResourceUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ResourceUtils.java index 80afdaf5f..426457c8e 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/ResourceUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ResourceUtils.java @@ -1,14 +1,17 @@ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; +import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; -import run.mone.m78.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Const; import lombok.SneakyThrows; +import org.HdrHistogram.AtomicHistogram; import java.io.File; import java.io.IOException; @@ -16,6 +19,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -29,6 +33,8 @@ public class ResourceUtils { public static final String USER_HOME_ATHENA_FILE_NAME = ".athena.json"; + private static final String ULTRAMAN_URL_PREFIX = "http://localhost/ultraman"; + public static String readResources(Project project, Module module) { try { StringBuilder stringBuilder = new StringBuilder(); @@ -74,15 +80,32 @@ public static Map getAthenaConfig(Project project, boolean refre str = System.getProperty("user.home") + File.separator + USER_HOME_ATHENA_FILE_NAME; config.putAll(defaultConfig); getConfig(str); + + //todo 未来版本删除 + String dashUrl = config.get(Const.CONF_DASH_URL); + if (dashUrl.startsWith(ULTRAMAN_URL_PREFIX)) { + config.put(Const.CONF_DASH_URL, defaultConfig.get(Const.CONF_DASH_URL)); + String content = new GsonBuilder().setPrettyPrinting().create().toJson(config); + FileUtils.writeConfig(content, ResourceUtils.USER_HOME_ATHENA_FILE_NAME); + } + + // 把OPEN_GUIDE强制置为true todo 未来版本删除? + String openGuide = config.get(Const.OPEN_GUIDE); + if ("false".equals(openGuide)) { + config.put(Const.OPEN_GUIDE, "true"); + String content = new GsonBuilder().setPrettyPrinting().create().toJson(config); + FileUtils.writeConfig(content, ResourceUtils.USER_HOME_ATHENA_FILE_NAME); + } + return config; } - private static Map defaultConfig = new HashMap<>() { + private static Map defaultConfig = new LinkedHashMap<>() { { put(Const.VISION, "false"); put(Const.DEBUG, "false"); - put(Const.OPEN_GUIDE, "false"); + put(Const.OPEN_GUIDE, "true"); put(Const.DISABLE_ACTION_GROUP, "false"); put(Const.BIZ_WRITE, "false"); put(Const.OPEN_AI_KEY, ""); @@ -93,7 +116,32 @@ public static Map getAthenaConfig(Project project, boolean refre put(Const.OPEN_AI_MODEL, "gpt-4-1106-preview");//gpt-3.5-turbo put(Const.DISABLE_SEARCH, "false"); put(Const.AI_PROXY_CHAT, "true"); - put(Const.ENABLE_ATHENA_STATUS_BAR, "false"); + put(Const.ENABLE_ATHENA_STATUS_BAR, "true"); + //调用bot + put(Const.USE_BOT, "true"); + put(Const.BOT_URL, "https://localhost/open-apis/ai-plugin-new/feature/router/probot/query"); + // inline 补全 + put(Const.INLAY, "true"); + put(Const.INLAY_DELAY, "200"); + put(Const.INLAY_BOT_ID, "160004"); + put(Const.INLAY_SCOPE, "method"); + //关闭整个代码补全功能(只留下chat) + put(Const.DISABLE_CODE_COMPLETION, Const.FALSE); + // 内置配置 + put(Const.CONF_NICK_NAME, "nick_mone"); + put(Const.CONF_DASH_URL, "http://127.0.0.1/ultraman/#/code"); + put(Const.CONF_AI_PROXY_URL, "http://127.0.0.1"); + //允许flow回调回来的端口号 + put(Const.CONF_PORT, "6666"); + put(Const.CONF_M78_URL, "https://localhost/open-apis/ai-plugin-new"); + put(Const.CONF_M78_SPEECH2TEXT, "/speechToText2"); + put(Const.CONF_M78_TEXT2SPEECH, "/textToSpeech"); + put(Const.CONF_M78_UPLOAD_CODE_INFO, "/uploadCodeInfo"); + // 右侧聊天是否调用BOT配置 + put(Const.CONF_CHAT_USE_BOT, "true"); + put(Const.CONF_M78_CODE_GEN_WITH_ENTER, "false"); + +// put(Const.CONF_COMPLETION_TYPE, "0"); } }; @@ -120,9 +168,26 @@ public static Map getAthenaConfig() { return getAthenaConfig(null, false); } + public static boolean isOpen(String key) { + return Boolean.valueOf(ResourceUtils.getAthenaConfig().getOrDefault(key, "false")); + } + + public static boolean has(String key) { + return ResourceUtils.getAthenaConfig().containsKey(key); + } + + public static String get(String key, String defaultValue) { + return ResourceUtils.getAthenaConfig().getOrDefault(key, defaultValue); + } + public static void putConfigIfAbsent(String key, String value) { config.putIfAbsent(key, value); } + public static boolean checkDisableCodeCompletionStatus() { + return isOpen(Const.DISABLE_CODE_COMPLETION); + } + + } diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/RunUntil.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/RunUntil.java similarity index 95% rename from athena-all/src/main/java/run/mone/m78/ip/util/RunUntil.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/RunUntil.java index 2e7fbf574..18cbf57fa 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/RunUntil.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/RunUntil.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.intellij.execution.RunManager; import com.intellij.execution.RunnerAndConfigurationSettings; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/RunUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/RunUtils.java new file mode 100644 index 000000000..b0b23d74c --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/RunUtils.java @@ -0,0 +1,52 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.RunManager; +import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.application.ApplicationConfiguration; +import com.intellij.execution.application.ApplicationConfigurationType; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; + +/** + * @author goodjava@qq.com + * @date 2024/4/27 22:17 + */ +public class RunUtils { + + public static void runMainMethod(Project project, PsiClass psiClass) { + // 检查是否存在 main 方法 + if (psiClass.findMethodsByName("main", false).length > 0) { + // 创建应用程序运行配置 + ApplicationConfiguration configuration = new ApplicationConfiguration("Run Main", project); + // 设置要运行的主类 + configuration.setMainClassName(psiClass.getQualifiedName()); + + // 创建执行环境 + Executor executor = DefaultRunExecutor.getRunExecutorInstance(); + RunnerAndConfigurationSettings runnerAndConfigurationSettings = RunManager.getInstance(project).createConfiguration(configuration, ApplicationConfigurationType.getInstance().getConfigurationFactories()[0]); + ExecutionEnvironment environment = new ExecutionEnvironment(executor, ProgramRunner.getRunner(executor.getId(), configuration), runnerAndConfigurationSettings, project); + + +// ExecutionUtil.runConfiguration(runnerAndConfigurationSettings, new DefaultDebugExecutor()); + + try { + ProgramRunner runner = ProgramRunner.getRunner(executor.getId(), configuration); + if (runner != null) { + runner.execute(environment); + } + } catch (ExecutionException e) { + e.printStackTrace(); + } + } else { + System.out.println("No main method found in class " + psiClass.getName()); + } + } + + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/ScreenSizeUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ScreenSizeUtils.java similarity index 96% rename from athena-all/src/main/java/run/mone/m78/ip/util/ScreenSizeUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ScreenSizeUtils.java index 0023e8cdc..ca7f7623c 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/ScreenSizeUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/ScreenSizeUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import java.awt.*; diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/SpringUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/SpringUtils.java similarity index 91% rename from athena-all/src/main/java/run/mone/m78/ip/util/SpringUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/SpringUtils.java index 063c30532..38e692a53 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/SpringUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/SpringUtils.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.intellij.psi.PsiAnnotation; import com.intellij.psi.PsiClass; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/TerminalUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/TerminalUtils.java new file mode 100644 index 000000000..b9af42715 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/TerminalUtils.java @@ -0,0 +1,167 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 com.xiaomi.youpin.tesla.ip.util; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowAnchor; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.openapi.wm.ex.ToolWindowManagerEx; +import com.intellij.terminal.JBTerminalPanel; +import com.intellij.terminal.JBTerminalWidget; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManager; +import com.jediterm.terminal.TerminalOutputStream; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.plugins.terminal.TerminalView; + +import javax.swing.*; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/7 11:21 + */ +@Slf4j +public class TerminalUtils { + + public static final String TERMINAL_ID = "Terminal"; + + @SneakyThrows + public static void show(Project project) { + ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); + ToolWindow terminal = toolWindowManager.getToolWindow(TERMINAL_ID); + if (terminal != null) { + terminal.show(null); + if (!terminal.isActive()) { + TimeUnit.SECONDS.sleep(1); + } + } + } + + + public static void send(Project project, String message) { + if (null == project) { + project = ProjectManager.getInstance().getOpenProjects()[0]; + } + ToolWindow terminal = ToolWindowManager.getInstance(project).getToolWindow("Terminal"); + JComponent root = terminal.getComponent(); + terminal.show(() -> { + JBTerminalPanel terminalPanel = (JBTerminalPanel) getPannel(root); + //执行history命令 + TerminalOutputStream is = terminalPanel.getTerminalOutputStream(); + if (null != is) { + is.sendString(message + "\n"); + } + }); + } + + public static ToolWindow getTerminalToolWindow(Project project) { + ToolWindowManagerEx toolWindowManager = ToolWindowManagerEx.getInstanceEx(project); + ToolWindow toolWindow = toolWindowManager.getToolWindow("Terminal"); + if (toolWindow == null) { + toolWindow = toolWindowManager.registerToolWindow("Terminal", true, ToolWindowAnchor.BOTTOM); + } + toolWindow.show(null); + return toolWindow; + } + + + public static void runCommandOnTerminal(Project project, String command) { + GeneralCommandLine cmdLine = new GeneralCommandLine(); + cmdLine.setExePath("/bin/bash"); // 设置 shell 解释器 + cmdLine.addParameter("-c"); // 添加参数 + cmdLine.addParameter(command); // 添加要执行的命令 + + OSProcessHandler processHandler = null; // 创建进程处理器 + try { + processHandler = new OSProcessHandler(cmdLine); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + + + processHandler.addProcessListener(new ProcessAdapter() { + @Override + public void onTextAvailable(ProcessEvent event, Key outputType) { + // 处理命令输出 + String output = event.getText(); + System.out.println(output); + } + }); + + processHandler.startNotify(); // 启动进程处理器 + + } + + + private static Object getPannel(Object root) { + if (root instanceof JBTerminalPanel) { + return root; + } + if (root instanceof JPanel) { + return getPannel(((JPanel) root).getComponent(0)); + } + if (root instanceof JLayeredPane) { + return getPannel(((JLayeredPane) root).getComponent(0)); + } + return null; + } + + + public static JBTerminalWidget getExistingTerminal(Project project) { + ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("Terminal"); + if (toolWindow != null) { + if (!toolWindow.isVisible()) { + // 获取终端工具窗口的内容管理器 + ContentManager contentManager = toolWindow.getContentManager(); + for (Content content : contentManager.getSelectedContents()) { + // 检查内容是否是终端视图 + if (content.getComponent() instanceof JBTerminalWidget) { + // 转换并返回JBTerminalWidget + return (JBTerminalWidget) content.getComponent(); + } + } + } + } + return null; + } + + public static void executeTerminalCommand(Project project, String command) { + ApplicationManager.getApplication().invokeLater(()->{ + TerminalView terminalView = TerminalView.getInstance(project); + try { + log.info("command:{}", command); + terminalView.createLocalShellWidget(project.getBasePath(), "Athena").executeCommand(command); + } catch (IOException err) { + err.printStackTrace(); + } + }); + } + + +} diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/TestUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/TestUtils.java new file mode 100644 index 000000000..681ed4cd1 --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/TestUtils.java @@ -0,0 +1,87 @@ +package com.xiaomi.youpin.tesla.ip.util; + +import com.google.common.collect.Lists; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.RunManager; +import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.application.ApplicationConfiguration; +import com.intellij.execution.application.ApplicationConfigurationType; +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.executors.DefaultDebugExecutor; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.junit.JUnitConfiguration; +import com.intellij.execution.junit.JUnitConfigurationType; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.ExecutionUtil; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/8/11 09:46 + */ +public class TestUtils { + + + public static List junitImportList = Lists.newArrayList("import org.junit.Test", "import org.junit.Assert"); + + public static List jupiterImportList = Lists.newArrayList("import org.junit.jupiter.api.Test", "import static org.junit.jupiter.api.Assertions.assertEquals", "import static org.junit.jupiter.api.Assertions.assertNotNull"); + + + public static boolean isJupiter() { + if (isClassPresent("org.junit.Test")) { + return false; + } else if (isClassPresent("org.junit.jupiter.api.Test")) { + return true; + } else { + return false; + } + } + + public static List getImportList(String version) { + if (version.equals("unknow")) { + return Lists.newArrayList(); + } + if (version.equals("junit")) { + return junitImportList; + } + if (version.equals("jupiter")) { + return junitImportList; + } + return Lists.newArrayList(); + } + + + private static boolean isClassPresent(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + + + public static void runAllTestsInClass(Project project, PsiClass psiClass) { + // 创建 JUnit 测试配置 + JUnitConfiguration configuration = new JUnitConfiguration("Run all tests in " + psiClass.getName(), project); + // 设置要运行的测试类 + configuration.setMainClass(psiClass); + // 创建 RunnerAndConfigurationSettings 对象 + RunnerAndConfigurationSettings runnerAndConfigurationSettings = RunManager.getInstance(project).createConfiguration(configuration, getJUnitConfigurationFactory()); + // 运行测试 + ExecutionUtil.runConfiguration(runnerAndConfigurationSettings, new DefaultDebugExecutor()); + } + + + + private static ConfigurationFactory getJUnitConfigurationFactory() { + return JUnitConfigurationType.getInstance().getConfigurationFactories()[0]; + } + + +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/UltramanConsole.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/UltramanConsole.java similarity index 51% rename from athena-all/src/main/java/run/mone/m78/ip/util/UltramanConsole.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/UltramanConsole.java index 9933160d0..b73b80c0b 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/UltramanConsole.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/UltramanConsole.java @@ -14,14 +14,20 @@ * limitations under the License. */ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowManager; -import run.mone.m78.ip.common.Safe; +import com.intellij.ui.content.Content; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Safe; +import org.jetbrains.annotations.Nullable; import run.mone.ultraman.common.SafeRun; +import javax.swing.*; + /** * @Author goodjava@qq.com * @Date 2021/11/9 17:13 @@ -34,7 +40,7 @@ public static void append(String message) { } public static void append(String projectName, String messsage) { - SafeRun.run(()-> append(ProjectUtils.projectFromManager(projectName), messsage)); + SafeRun.run(() -> append(ProjectUtils.projectFromManager(projectName), messsage)); } @@ -43,12 +49,32 @@ public static void append(Project project, String message) { } public static void append(Project project, String message, boolean enableAutoWrap) { + ApplicationManager.getApplication().invokeLater(() -> { + Safe.run(() -> { + ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(Const.MIONE_CONSOLE_NAME); + + @Nullable Content c = toolWindow.getContentManager().getContent(0); + if (null == c) { + return; + } + JScrollPane jpanel = (JScrollPane) toolWindow.getContentManager() + .getContent(0).getComponent().getComponent(0); + JViewport viewPort = jpanel.getViewport(); + JTextArea textArea = (JTextArea) viewPort.getComponent(0); + if (textArea != null) { + textArea.append(message); + if (enableAutoWrap) { + textArea.append("\n"); + } + } + }); + }); } public static void show() { Safe.run(() -> { - ToolWindow toolWindow = ToolWindowManager.getInstance(ProjectUtils.project()).getToolWindow("AthenaConsole"); + ToolWindow toolWindow = ToolWindowManager.getInstance(ProjectUtils.project()).getToolWindow(Const.MIONE_CONSOLE_NAME); toolWindow.show(); }); } diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/WindowUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/WindowUtils.java similarity index 91% rename from athena-all/src/main/java/run/mone/m78/ip/util/WindowUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/WindowUtils.java index 71721bd92..73d92ee9d 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/WindowUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/WindowUtils.java @@ -1,4 +1,4 @@ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.ToolWindow; diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/XmlUtils.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/XmlUtils.java similarity index 50% rename from athena-all/src/main/java/run/mone/m78/ip/util/XmlUtils.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/XmlUtils.java index 639998347..48c3600d2 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/util/XmlUtils.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/util/XmlUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package run.mone.m78.ip.util; +package com.xiaomi.youpin.tesla.ip.util; import com.google.common.collect.Maps; import com.intellij.openapi.application.ApplicationManager; @@ -25,12 +25,22 @@ import lombok.SneakyThrows; import org.jetbrains.annotations.Nullable; import org.w3c.dom.Document; +import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; import run.mone.ultraman.AthenaContext; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.File; +import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -40,6 +50,10 @@ public class XmlUtils { + public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException { + System.out.println(getKV("/tmp/databank/databank-service/pom.xml", "manifestEntries")); + } + public static Map getKV(String filePath, String tagName) { Map res = new HashMap<>(5); @@ -85,13 +99,56 @@ public static String getGeneratorConfigPath(String projectName, String moduleNam @SneakyThrows public static Map getMysqlConfigFromMybatisConfig(String path) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(new File(path)); + NodeList nodeList = document.getElementsByTagName("jdbcConnection"); + if (nodeList.getLength() == 1) { + Element element = (Element) nodeList.item(0); + String dbUrl = element.getAttribute("connectionURL"); + String dbPassword = element.getAttribute("password"); + String dbName = element.getAttribute("userId"); + Map res = new HashMap<>(); + res.put("dbUrl", dbUrl); + res.put("dbPassword", dbPassword); + res.put("dbName", dbName); + return res; + } return Maps.newHashMap(); } public static void updateGeneratorConfig(String path, String newName) { + try { + // 初始化 DocumentBuilderFactory + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + // 解析现有的 XML 文件 + Document document = builder.parse(new File(path)); + // 查找所有名为 "tableName" 的元素 + NodeList nodeList = document.getElementsByTagName("table"); + if (nodeList.getLength() == 1) { + for (int i = 0; i < nodeList.getLength(); i++) { + Element element = (Element) nodeList.item(i); + element.setAttribute("domainObjectName", newName); + element.setAttribute("tableName", newName); + } + // 将修改后的 DOM 写回文件 + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + + transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"); + transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"); + DOMSource source = new DOMSource(document); + StreamResult result = new StreamResult(new File(path)); + transformer.transform(source, result); + System.out.println("XML file updated successfully"); + } + } catch (Exception e) { + e.printStackTrace(); + } } diff --git a/athena-all/src/main/java/run/mone/m78/ip/window/UltramanConsoleWindowFactory.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/window/UltramanConsoleWindowFactory.java similarity index 93% rename from athena-all/src/main/java/run/mone/m78/ip/window/UltramanConsoleWindowFactory.java rename to athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/window/UltramanConsoleWindowFactory.java index 71d6acb7b..800764ee2 100644 --- a/athena-all/src/main/java/run/mone/m78/ip/window/UltramanConsoleWindowFactory.java +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/window/UltramanConsoleWindowFactory.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package run.mone.m78.ip.window; +package com.xiaomi.youpin.tesla.ip.window; import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowFactory; import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentFactory; -import run.mone.m78.ip.ui.UltramanConsoleUi; +import com.xiaomi.youpin.tesla.ip.ui.UltramanConsoleUi; import org.jetbrains.annotations.NotNull; import javax.swing.*; diff --git a/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/window/UltramanWindowFactory.java b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/window/UltramanWindowFactory.java new file mode 100644 index 000000000..b9b619e1d --- /dev/null +++ b/athena-all/src/main/java/com/xiaomi/youpin/tesla/ip/window/UltramanWindowFactory.java @@ -0,0 +1,85 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 com.xiaomi.youpin.tesla.ip.window; + +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowFactory; +import com.intellij.openapi.wm.ex.ToolWindowEx; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentFactory; +import com.intellij.ui.jcef.JBCefBrowser; +import com.xiaomi.youpin.tesla.ip.common.NotificationCenter; +import com.xiaomi.youpin.tesla.ip.listener.UltrmanTreeKeyAdapter; +import com.xiaomi.youpin.tesla.ip.ui.UltramanTreeUi; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.List; + +/** + * @Author goodjava@qq.com + * @Date 2021/11/8 20:55 + */ +public class UltramanWindowFactory implements ToolWindowFactory, DumbAware { + + private static final String nginxChatUrl = "http://127.0.0.1/ultraman/#/code"; + + @Override + public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) { + ContentFactory contentFactory = ContentFactory.getInstance(); + JPanel pannel = new UltramanTreeUi(project).jpanel(); + Content content = contentFactory.createContent(pannel, "", false); + toolWindow.getContentManager().addContent(content); + if (toolWindow instanceof ToolWindowEx toolWindowEx) { + toolWindowEx.setAdditionalGearActions(new AthenaWindowCustomActionGroup()); + } + } + + private static class AthenaWindowCustomActionGroup extends ActionGroup { + @Override + public AnAction @NotNull [] getChildren(@Nullable AnActionEvent e) { + List actions = new ArrayList<>(); + actions.add(new AthenaWindowCustomRefreshAction()); + return actions.toArray(new AnAction[0]); + } + } + + private static class AthenaWindowCustomRefreshAction extends AnAction { + + public AthenaWindowCustomRefreshAction() { + super("Force Refresh"); + } + + @Override + public void actionPerformed(AnActionEvent e) { + // 自定义选项的操作 + NotificationCenter.notice(null, "custom refresh action performed!", true); + Project project = e.getProject(); + if (project != null) { + JBCefBrowser jbCefBrowser = UltrmanTreeKeyAdapter.browserMap.get(project.getName()); + UltrmanTreeKeyAdapter.forceRefresh(jbCefBrowser, nginxChatUrl); + } + } + } +} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/ActionChain.java b/athena-all/src/main/java/run/mone/m78/ip/action/ActionChain.java deleted file mode 100644 index 045dfff3b..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/ActionChain.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.action; - -import com.intellij.openapi.actionSystem.AnActionEvent; -import run.mone.m78.ip.common.Context; -import run.mone.m78.ip.service.*; - -/** - * @Author goodjava@qq.com - * @Date 2021/11/7 21:00 - */ -public class ActionChain { - - - private AbstractService testService; - - public void init() { - testService = new TestService(); - - ChatGptService chatGptService = new ChatGptService(); - testService.setNext(chatGptService); - - CodeService codeService = new CodeService(); - chatGptService.setNext(codeService); - - MusicService musicService = MusicService.ins(); - codeService.setNext(musicService); - - ImageService imageService = new ImageService(); - musicService.setNext(imageService); - - UserService userService = new UserService(); - imageService.setNext(userService); - - } - - - public void execute(Context context, AnActionEvent e) { - testService.execute(context, e); - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/ActionEnum.java b/athena-all/src/main/java/run/mone/m78/ip/action/ActionEnum.java deleted file mode 100644 index 0d41861da..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/ActionEnum.java +++ /dev/null @@ -1,16 +0,0 @@ -package run.mone.m78.ip.action; - -/** - * @Author goodjava@qq.com - * @Date 2021/11/2 11:25 - */ -public enum ActionEnum { - - zero,//image - diga,//music - diga_stop, - background, - code_upload, - code_download, - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/AthenaAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/AthenaAction.java deleted file mode 100644 index c49b35b7c..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/AthenaAction.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.action; - -import com.intellij.ide.util.PropertiesComponent; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.wm.impl.IdeBackgroundUtil; -import run.mone.m78.ip.common.ApiCall; -import run.mone.m78.ip.common.Context; -import run.mone.m78.ip.common.NotificationCenter; -import run.mone.m78.ip.util.EditorUtils; -import org.jetbrains.annotations.NotNull; - -/** - * @author goodjava@qq.com - */ -public class AthenaAction extends AnAction { - - private static final Logger log = Logger.getInstance(AthenaAction.class); - - @Override - public void actionPerformed(@NotNull AnActionEvent e) { - String content = getText(e); - log.info("Ultraman req:" + content); - ActionChain chain = new ActionChain(); - chain.init(); - Context context = new Context(); - context.setContent(content); - chain.execute(context, e); - if (content.equals(ActionEnum.background.name())) { - NotificationCenter.notice("background"); - log.info("background"); - String image = new ApiCall().callOne(ApiCall.IMAGE_API); - PropertiesComponent prop = PropertiesComponent.getInstance(); - prop.setValue(IdeBackgroundUtil.FRAME_PROP, null); - prop.setValue(IdeBackgroundUtil.EDITOR_PROP, image); - IdeBackgroundUtil.repaintAllWindows(); - return; - } - } - - private String getText(AnActionEvent anActionEvent) { - Editor editor = anActionEvent.getData(PlatformDataKeys.EDITOR); - return EditorUtils.getSelectContent(editor); - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/ChatAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/ChatAction.java deleted file mode 100644 index 779ab8181..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/ChatAction.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.action; - -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; -import run.mone.m78.ip.component.ChatComponent; -import org.jetbrains.annotations.NotNull; - -/** - * @author goodjava@qq.com - */ -public class ChatAction extends AnAction { - - @Override - public void actionPerformed(@NotNull AnActionEvent anActionEvent) { - Application application = ApplicationManager.getApplication(); - ChatComponent component= application.getComponent(ChatComponent.class); - component.show(anActionEvent.getProject(),anActionEvent); - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/CommonAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/CommonAction.java deleted file mode 100644 index c930fdbab..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/CommonAction.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.action; - -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.project.Project; -import org.jetbrains.annotations.NotNull; - -/** - * @author goodjava@qq.com - */ -public class CommonAction extends AnAction { - - - - @Override - public void actionPerformed(@NotNull AnActionEvent anActionEvent) { - Project project = anActionEvent.getData(PlatformDataKeys.PROJECT); - String projectName = project.getName(); - String basePath = project.getBasePath(); -// Messages.showMessageDialog(project, projectName + ":" + basePath, "", Messages.getInformationIcon()); - String title = "title"; - String content = "content"; - - - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/CreateFilterAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/CreateFilterAction.java deleted file mode 100644 index b25d89ec5..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/CreateFilterAction.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.action; - -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; -import run.mone.m78.ip.component.FilterComponent; -import org.jetbrains.annotations.NotNull; - -public class CreateFilterAction extends AnAction { - - @Override - public void actionPerformed(@NotNull AnActionEvent anActionEvent) { - Application application = ApplicationManager.getApplication(); - FilterComponent myComponent = application.getComponent(FilterComponent.class); - myComponent.show(anActionEvent.getProject()); - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/CreateProjectAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/CreateProjectAction.java deleted file mode 100644 index 3dbf2518f..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/CreateProjectAction.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.action; - -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; -import run.mone.m78.ip.component.CreateProjectComponent; -import org.jetbrains.annotations.NotNull; - -/** - * @author goodjava@qq.com - */ -public class CreateProjectAction extends AnAction { - - @Override - public void actionPerformed(@NotNull AnActionEvent anActionEvent) { - Application application = ApplicationManager.getApplication(); - CreateProjectComponent myComponent = application.getComponent(CreateProjectComponent.class); - myComponent.show(anActionEvent.getProject()); - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/CreateSprintBootProjectAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/CreateSprintBootProjectAction.java deleted file mode 100644 index bdaae8bac..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/CreateSprintBootProjectAction.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.action; - -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.application.Application; -import com.intellij.openapi.application.ApplicationManager; -import run.mone.m78.ip.component.CreateSpringBootProjectComponent; -import org.jetbrains.annotations.NotNull; - -/** - * @author goodjava@qq.com - */ -public class CreateSprintBootProjectAction extends AnAction { - - @Override - public void actionPerformed(@NotNull AnActionEvent anActionEvent) { - Application application = ApplicationManager.getApplication(); - CreateSpringBootProjectComponent myComponent = application.getComponent(CreateSpringBootProjectComponent.class); - myComponent.show(anActionEvent.getProject()); - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/DynamicActionGroup.java b/athena-all/src/main/java/run/mone/m78/ip/action/DynamicActionGroup.java deleted file mode 100644 index a3fdb2ca7..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/DynamicActionGroup.java +++ /dev/null @@ -1,27 +0,0 @@ -package run.mone.m78.ip.action; - -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.bo.PromptInfo; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author goodjava@qq.com - * @date 2023/5/27 09:23 - */ -public class DynamicActionGroup extends ActionGroup { - - @Override - public AnAction @NotNull [] getChildren(@Nullable AnActionEvent event) { - List actions = new ArrayList<>(); - List list = Prompt.promptList("plugin"); - list.stream().forEach(it -> actions.add(new DynamicAction(it.getDesc(), Prompt.getPromptType(it), it))); - return actions.toArray(new AnAction[0]); - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/MenuAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/MenuAction.java deleted file mode 100644 index f078b8f15..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/MenuAction.java +++ /dev/null @@ -1,32 +0,0 @@ -package run.mone.m78.ip.action; - -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.bo.PromptInfo; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author caobaoyu - * @description: - * @date 2023-06-14 14:50 - */ -public class MenuAction extends ActionGroup { - - private List promptInfoList; - - public MenuAction(String text, List promptInfos) { - super(text, true); - this.promptInfoList = promptInfos; - } - - @Override - public AnAction @NotNull [] getChildren(@Nullable AnActionEvent e) { - return new AnAction[]{}; - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/MenuActionGroup.java b/athena-all/src/main/java/run/mone/m78/ip/action/MenuActionGroup.java deleted file mode 100644 index 0f1fa9db9..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/MenuActionGroup.java +++ /dev/null @@ -1,37 +0,0 @@ -package run.mone.m78.ip.action; - -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.common.Const; -import run.mone.m78.ip.util.LabelUtils; -import org.jetbrains.annotations.NotNull; - -import java.util.*; - -/** - * @author caobaoyu - * @author goodjava@qq.com - * @description: - * @date 2023-06-14 14:15 - */ -public class MenuActionGroup extends ActionGroup { - - public MenuActionGroup() { - super("Prompt", true); - } - - @Override - public AnAction @NotNull [] getChildren(AnActionEvent e) { - if (LabelUtils.getLabelValue(e.getProject(), Const.DISABLE_ACTION_GROUP, "false").equals("true")) { - return new AnAction[]{}; - } - List list = Prompt.getPromptInfoByTag(""); - list.addAll(Prompt.getCollected()); - return list.stream().map(it -> new DynamicAction(it.getDesc(), Prompt.getPromptType(it), it)).toArray(AnAction[]::new); - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/action/TestAction.java b/athena-all/src/main/java/run/mone/m78/ip/action/TestAction.java deleted file mode 100644 index 5048bfa2d..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/action/TestAction.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.action; - -import com.google.common.collect.Maps; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiFile; -import run.mone.m78.ip.service.ScriptService; - -/** - * @author goodjava@qq.com - */ -public class TestAction extends AnAction { - - @Override - public void actionPerformed(AnActionEvent e) { - //获取当前在操作的工程上下文 - Project project = e.getData(PlatformDataKeys.PROJECT); - - //获取当前操作的类文件 - PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE); - //获取当前类文件的路径 - String classPath = ""; - if (null != psiFile) { - classPath = psiFile.getVirtualFile().getPath(); - } - String title = "Hello World!"; - //显示对话框 - //Messages.showMessageDialog(project, classPath, title, Messages.getInformationIcon()); - - ScriptService.ins().invoke("def sum() {return 1+2}","sum", Maps.newHashMap(), Maps.newHashMap()); - - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/client/GrpcClient.java b/athena-all/src/main/java/run/mone/m78/ip/client/GrpcClient.java deleted file mode 100644 index 7b40a78d6..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/client/GrpcClient.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.client; - -import com.google.gson.Gson; -import com.intellij.ide.util.PropertiesComponent; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.ui.Messages; -import com.intellij.util.messages.MessageBus; -import com.intellij.util.messages.MessageBusConnection; -import run.mone.m78.ip.util.HintUtils; -import run.mone.m78.ip.util.ProjectUtils; -import run.mone.mone.ultraman.grpc.UltramanRequest; -import run.mone.mone.ultraman.grpc.UltramanResponse; -import run.mone.mone.ultraman.grpc.UltramanServiceGrpc; -import run.mone.m78.ip.action.ActionEnum; -import run.mone.m78.ip.bo.TeslaPluginConfig; -import run.mone.m78.ip.common.NotificationCenter; -import run.mone.m78.ip.common.PluginVersion; -import run.mone.m78.ip.common.UltramanNotifier; -import run.mone.m78.ip.service.DocumentService; -import run.mone.m78.ip.service.ImageService; -import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; -import io.grpc.stub.StreamObserver; -import org.apache.commons.lang.mutable.MutableObject; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * @Author goodjava@qq.com - * @Date 2021/11/5 10:42 - */ -public class GrpcClient { - - private ManagedChannel channel; - - private TeslaPluginConfig config; - - private String ip; - - private boolean close = true; - - public void init() { - if (close) { - return; - } - - String v = PropertiesComponent.getInstance().getValue("tesla_plugin_token"); - if (null != v) { - try { - config = new Gson().fromJson(v, TeslaPluginConfig.class); - if (!StringUtils.equals(config.getChatServer(), ip)) { - try { - channel.shutdownNow(); - } catch (Throwable ex) { - } - } - - ip = config.getChatServer(); - System.out.println("Ultraman grpc channel build"); - channel = ManagedChannelBuilder.forAddress(ip, 5555).usePlaintext().build(); - - new Thread(() -> { - int i = 0; - MessageBusConnection connection = null; - for (; ; ) { - System.out.println("connect grpc num:" + (i++)); - CountDownLatch latch = new CountDownLatch(1); - try { - UltramanResponse res = call(UltramanRequest.newBuilder().setCmd("version").build()); - if (null != res && (Integer.valueOf(res.getData()) > Integer.valueOf(new PluginVersion().toString()))) { - //需要升级 - ApplicationManager.getApplication().invokeLater(() -> { - NotificationCenter.notice("Ultraman Plugin Update"); - }); - } - StreamObserver streamObserver = this.listener(latch); - MessageBus messageBus = ApplicationManager.getApplication().getMessageBus(); - connection = messageBus.connect(); - connection.subscribe(UltramanNotifier.ULTRAMAN_ACTION_TOPIC, event -> { - System.out.println(event.getCmd()); - switch (event.getCmd()) { - case "save_config": { - break; - } - case "req": { - streamObserver.onNext((UltramanRequest) event.getData()); - break; - } - } - }); - } catch (Throwable ex) { - ex.printStackTrace(); - latch.countDown(); - } - try { - latch.await(); - TimeUnit.SECONDS.sleep(3); - } catch (Throwable ex) { - - } finally { - if (null != connection) { - connection.disconnect(); - } - } - } - }).start(); - } catch (Throwable ex) { - System.out.println("Ultraman error:" + ex.getMessage()); - } - } else { - ApplicationManager.getApplication().invokeLater(() -> { - Messages.showMessageDialog("请初始化Ultraman配置(user)", "message", Messages.getInformationIcon()); - }); - } - } - - public UltramanResponse call(UltramanRequest req) { - UltramanServiceGrpc.UltramanServiceBlockingStub stub2 = UltramanServiceGrpc.newBlockingStub(channel); - UltramanResponse res = stub2.hello(req); - return res; - } - - public StreamObserver listener(CountDownLatch latch) { - UltramanServiceGrpc.UltramanServiceStub stub = UltramanServiceGrpc.newStub(channel); - MutableObject mo = new MutableObject(); - final StreamObserver reqStream = stub.stream(new StreamObserver() { - @Override - public void onNext(UltramanResponse res) { - System.out.println(res.getData()); - //通知 - if (res.getCmd().equals("notify")) { - String data = res.getData(); - if (!res.getResMapOrDefault("user", "").equals("")) { - data = res.getResMapOrDefault("user", "") + ":" + data; - } - String type = res.getResMapOrDefault("type", "0"); - if (type.equals("0")) { - NotificationCenter.notice(data); - HintUtils.show(null, data); - } else { - HintUtils.show(null, data); - } - } - //查看图片 - if (res.getCmd().equals("image")) { - new ImageService().open(ActionEnum.zero.name()); - } - //显示代码 - if (res.getCmd().equals("show_code")) { - MutableObject moc = new MutableObject(); - ApplicationManager.getApplication().invokeAndWait(() -> { - int v = Messages.showOkCancelDialog(ProjectUtils.project(), "有人给你推送了代码,是否选择查看", "选择", Messages.getInformationIcon()); - moc.setValue(v); - }); - if ((int) moc.getValue() == 0) { - new DocumentService().open(res.getResMapMap().get("fileName"), res.getData()); - } - } - //查看代码(别人主动要看代码,返回我的代码) - if (res.getCmd().equals("begin_review")) { - String user = res.getResMapMap().get("review"); - - MutableObject moc = new MutableObject(); - ApplicationManager.getApplication().invokeAndWait(() -> { - int v = Messages.showOkCancelDialog(ProjectUtils.project(), user + "想要查看你当前的code", "选择", Messages.getInformationIcon()); - moc.setValue(v); - }); - - if ((int) moc.getValue() != 0) { - return; - } - - Pair data = new DocumentService().getContent(null); - if (null == data) { - data = Pair.of("对方没有打开源码", "tmp.java"); - } - StreamObserver reqStream = (StreamObserver) mo.getValue(); - UltramanRequest req = UltramanRequest.newBuilder().setCmd("begin_review_res") - .setParams(data.getKey()) - .putParamMap("fileName", data.getValue()) - .putParamMap("review", user) - .putParamMap("user", res.getResMapMap().get("user")) - .build(); - reqStream.onNext(req); - } - } - - @Override - public void onError(Throwable throwable) { - throwable.printStackTrace(); - latch.countDown(); - } - - @Override - public void onCompleted() { - latch.countDown(); - } - }); - mo.setValue(reqStream); - UltramanRequest loginReq = UltramanRequest.newBuilder().setCmd("login").putParamMap("user", config.getNickName()).build(); - reqStream.onNext(loginReq); - return reqStream; - - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ChromeUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/ChromeUtils.java deleted file mode 100644 index 6c2ddf175..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/common/ChromeUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -package run.mone.m78.ip.common; - -import com.google.gson.Gson; -import run.mone.m78.ip.bo.robot.AiChatMessage; -import lombok.SneakyThrows; - -/** - * @author goodjava@qq.com - * @date 2023/6/2 16:44 - */ -public class ChromeUtils { - - private static final Gson gson = new Gson(); - - @SneakyThrows - public static void call(String projectName, String method, String param, boolean useReq) { - - } - - - public static void call(String projectName, String param, int code) { - call(projectName, param, "", code); - } - - public static void call(String projectName, String param, String sound, int code) { - - } - - public static void call(String projectName, AiChatMessage res) { - - } - - - public static void call(String projectName, String method, String param) { - call(projectName, method, param, false); - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ColorEggUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/ColorEggUtils.java deleted file mode 100644 index 95ef501cc..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/common/ColorEggUtils.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.common; - -import javax.crypto.Cipher; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.DESKeySpec; -import java.security.SecureRandom; - -public class ColorEggUtils { - - /** - * 加密 - * - * @param content - * 待加密内容 - * @param key - * 加密的密钥 - * @return - */ - public static byte[] encrypt(String content, String key) { - try { - SecureRandom random = new SecureRandom(); - DESKeySpec desKey = new DESKeySpec(key.getBytes()); - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); - SecretKey securekey = keyFactory.generateSecret(desKey); - Cipher cipher = Cipher.getInstance("DES"); - cipher.init(Cipher.ENCRYPT_MODE, securekey, random); - byte[] result = cipher.doFinal(content.getBytes()); - return result; - } catch (Throwable e) { - e.printStackTrace(); - } - return null; - } - - /** - * 解密 - * - * @param content - * 待解密内容 - * @param key - * 解密的密钥 - * @return - */ - public static String decrypt(byte[] content, String key) { - try { - SecureRandom random = new SecureRandom(); - DESKeySpec desKey = new DESKeySpec(key.getBytes()); - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); - SecretKey securekey = keyFactory.generateSecret(desKey); - Cipher cipher = Cipher.getInstance("DES"); - cipher.init(Cipher.DECRYPT_MODE, securekey, random); - byte[] result = cipher.doFinal(content); - return new String(result); - } catch (Throwable e) { - e.printStackTrace(); - } - return null; - } - - - /** - * 将二进制转换成16进制 - * - * @param buf - * @return - */ - public static String parseByte2HexStr(byte buf[]) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < buf.length; i++) { - String hex = Integer.toHexString(buf[i] & 0xFF); - if (hex.length() == 1) { - hex = '0' + hex; - } - sb.append(hex); - } - return sb.toString(); - } - - /** - * hex字符串转byte数组 - * @param inHex 待转换的Hex字符串 - * @return 转换后的byte数组结果 - */ - public static byte[] hexToByteArray(String inHex){ - int hexlen = inHex.length(); - byte[] result; - if (hexlen % 2 == 1){ - //奇数 - hexlen++; - result = new byte[(hexlen/2)]; - inHex="0"+inHex; - }else { - //偶数 - result = new byte[(hexlen/2)]; - } - int j=0; - for (int i = 0; i < hexlen; i+=2){ - result[j]=hexToByte(inHex.substring(i,i+2)); - j++; - } - return result; - } - - public static byte hexToByte(String inHex){ - return (byte)Integer.parseInt(inHex,16); - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/ConfigCenter.java b/athena-all/src/main/java/run/mone/m78/ip/common/ConfigCenter.java deleted file mode 100644 index 330b88b98..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/common/ConfigCenter.java +++ /dev/null @@ -1,51 +0,0 @@ -package run.mone.m78.ip.common; - -import run.mone.m78.ip.bo.AiCodeRes; -import run.mone.m78.ip.bo.Tag; -import lombok.Data; -import lombok.Getter; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -/** - * @author caobaoyu - * @description: 从Z获取一些基础配置 对应 -> 68 Athena の cfg center - * @date 2023-05-30 11:02 - */ -@Data -public class ConfigCenter { - - - private static Map copyrightingMap = new HashMap<>(); - - @Getter - private static List guide = new ArrayList<>(); - - private static List menuTag = new ArrayList<>(); - - public static Map getMenuTag() { - return menuTag.stream().collect(Collectors.toMap(Tag::getName, Function.identity())); - } - - public static void init(String zAddr) { - guide.clear(); - menuTag.clear(); - buildCopyrighting(zAddr); - } - - private static void buildCopyrighting(String zAddr) { - - - } - - public static AiCodeRes build(String type) { - return copyrightingMap.get(type); - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Const.java b/athena-all/src/main/java/run/mone/m78/ip/common/Const.java deleted file mode 100644 index eeb5d3925..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/common/Const.java +++ /dev/null @@ -1,64 +0,0 @@ -package run.mone.m78.ip.common; - -import com.intellij.openapi.util.Key; -import com.intellij.util.messages.Topic; -import run.mone.ultraman.listener.AthenaMessageListener; - -/** - * @author goodjava@qq.com - * @date 2023/6/17 09:37 - */ -public interface Const { - - String MODULE_FILE_NAME = ""; - - String REQ_PACKAGE = "req_package"; - - String DEFAULT_REQ_PACKAGE = "run.mone.bo"; - - String DISABLE_SEARCH = "disable.search"; - - String AI_PROXY_CHAT = "ai.proxy.chat"; - - String ENABLE_ATHENA_STATUS_BAR = "enable.athena.status.bar"; - - String DISABLE_ACTION_GROUP = "disable.action.group"; - - String BIZ_WRITE = "biz_write"; - - String OPEN_AI_KEY = "open_ai_key"; - - String OPEN_AI_PROXY = "open_ai_proxy"; - - //直接本地调用chatgpt(local模式) - String OPEN_AI_LOCAL = "open_ai_local"; - - //本地测试 - String OPEN_AI_TEST = "open.ai.test"; - - //提问的时候是否开启选中的文本 - String OPEN_SELECT_TEXT = "open.select.text"; - - String OPEN_AI_MODEL = "open_ai_model"; - - String SEARCH = "search"; - - int UI_CANCEL_CODE = 555; - - String OPEN_GUIDE = "open.guide"; - - String DEBUG = "debug"; - - //多模态模式 - String VISION = "vision"; - - String CODE_SCRIPT = "code.script"; - - String TREE_SELECT = "tree.select"; - - Key T_KEY = new Key<>("t"); - - Topic ATHENA_TOPIC = new Topic(AthenaMessageListener.class); - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/JavaClassUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/JavaClassUtils.java deleted file mode 100644 index 8b0e0c2da..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/common/JavaClassUtils.java +++ /dev/null @@ -1,51 +0,0 @@ -package run.mone.m78.ip.common; - -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; - -/** - * @author goodjava@qq.com - * @date 2023/4/12 11:05 - */ -public abstract class JavaClassUtils { - - /** - * Create a class. - */ - public static void createClass(AnActionEvent e) { - createClass(e.getProject(), e.getData(PlatformDataKeys.EDITOR), "abc", ""); - } - - public static void createClass(Project project, Editor editor, String name, String code) { - - } - - - public static void createClass(Project project, Editor editor, String name, String code, boolean testClass) { - - } - - public static void createClass(Project project, Editor editor, String name, String code, boolean testClass, String packagePath) { - - } - - - public static void openClass(AnActionEvent e) { - - } - - public static void openClass(Project project, String className) { - - } - - - public static String getClassName(String className) { - String[] classNameParts = className.split("\\."); - String simpleClassName = classNameParts[classNameParts.length - 1]; - return simpleClassName; - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/Prompt.java b/athena-all/src/main/java/run/mone/m78/ip/common/Prompt.java deleted file mode 100644 index 0a570f5a2..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/common/Prompt.java +++ /dev/null @@ -1,142 +0,0 @@ -package run.mone.m78.ip.common; - -import com.google.gson.Gson; -import lombok.extern.slf4j.Slf4j; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.bo.Tag; -import run.mone.m78.ip.bo.ZAddrRes; -import run.mone.m78.ip.bo.ZPromptRes; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * @author goodjava@qq.com - * @author caobaoyu - * @date 2023/4/15 08:38 - */ -@Slf4j -public class Prompt { - - private static Map promptMap = new HashMap<>(); - - private static CopyOnWriteArrayList promptMeta = new CopyOnWriteArrayList<>(); - - private static String zAddr = ""; - - private static AtomicBoolean loadFinish = new AtomicBoolean(); - - public static String get(String key) { - return promptMap.get(key); - } - - public static List getPromptMeta() { - return promptMeta; - } - - public static boolean isLoadFinish() { - return loadFinish.get(); - } - - - private static Gson gson = new Gson(); - - public static void flush() { - init(); - } - - public static int size() { - return promptMap.size(); - } - - - public static void init() { - - } - - public static List getPrompt() { - return null; - } - - - public static PromptInfo getPrompt(int type, String name) { - return null; - } - - - /** - * 将Z的结果转换为实体 - * - * @param data - * @return - */ - private static List convertZResToInfo(List data) { - return null; - } - - public static List promptList(String tagName) { - return null; - } - - public static boolean containsTag(List tags, String tagName) { - return false; - } - - /** - * 查询是那种类型 - * - * @param info - * @return - */ - public static PromptType getPromptType(PromptInfo info) { - return null; - } - - - public static ZAddrRes zAddrRes() { - return null; - } - - private static void initConfig(ZAddrRes zAddrRes) { - - } - - - public static PromptInfo getPromptInfo(String promptName) { - return null; - } - - public static List getPromptInfoByTag(String tag) { - return null; - } - - public static List getCollected() { - return null; - } - - /** - * 获取使用次数最多的size个prompt - * - * @param size - * @return - */ - public static List getMostUsed(int size) { - return null; - } - - /** - * 获取某个标签下使用次数最多的size个prompt - * - * @param size - * @param tag - * @return - */ - public static List getMostUsed(int size, String tag) { - return null; - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/common/StringUtils.java b/athena-all/src/main/java/run/mone/m78/ip/common/StringUtils.java deleted file mode 100644 index f3694976f..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/common/StringUtils.java +++ /dev/null @@ -1,21 +0,0 @@ -package run.mone.m78.ip.common; - -/** - * @author goodjava@qq.com - * @date 2023/5/18 22:26 - */ -public abstract class StringUtils { - - public static String convertToCamelCase(String input) { - StringBuilder result = new StringBuilder(); - String[] words = input.split("_"); - result.append(words[0]); - for (int i = 1; i < words.length; i++) { - String word = words[i]; - String capitalizedWord = Character.toUpperCase(word.charAt(0)) + word.substring(1); - result.append(capitalizedWord); - } - return result.toString(); - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/component/UltramanComponent.java b/athena-all/src/main/java/run/mone/m78/ip/component/UltramanComponent.java deleted file mode 100644 index 30ffb9493..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/component/UltramanComponent.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.component; - -import com.intellij.openapi.components.ApplicationComponent; -import com.intellij.openapi.project.Project; -import run.mone.m78.ip.ui.UltramanUi; - -/** - * @Author goodjava@qq.com - * @Date 2021/10/31 19:17 - */ -public class UltramanComponent implements ApplicationComponent { - - - @Override - public String getComponentName() { - return "UltramanComponent"; - } - - - - public void show(Project project) { - UltramanUi dialog = new UltramanUi(); - dialog.setSize(600, 800); - dialog.setLocationRelativeTo(null); - dialog.setVisible(true); - dialog.setResizable(false); - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/PromptHandler.java b/athena-all/src/main/java/run/mone/m78/ip/listener/PromptHandler.java deleted file mode 100644 index 0b50137c4..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/listener/PromptHandler.java +++ /dev/null @@ -1,50 +0,0 @@ -package run.mone.m78.ip.listener; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.SelectionModel; -import com.intellij.openapi.project.Project; -import run.mone.m78.ip.service.CodeService; -import run.mone.m78.ip.bo.robot.AiChatMessage; -import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; -import run.mone.m78.ip.bo.robot.Role; -import run.mone.m78.ip.common.Const; -import run.mone.m78.ip.service.LocalAiService; -import run.mone.m78.ip.util.ResourceUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.mutable.MutableObject; -import run.mone.ultraman.manager.ConsoleViewManager; -import run.mone.ultraman.service.AiCodeService; -import run.mone.ultraman.state.ProjectFsmManager; - -import java.util.UUID; - -/** - * @author goodjava@qq.com - * @date 2023/12/10 16:01 - */ -public class PromptHandler { - - - //修改用户的问题 - public static String handler(Project project, Req req) { - return ""; - } - - //根据给定的提示更改提示信息,并在需要的情况下生成代码 - private static void changePrompt(Project project, String prompt, MutableObject r, Req req) { - - } - - - //移除选择 - private static void removeSelection(Project project) { - ApplicationManager.getApplication().invokeAndWait(() -> { - Editor editor = CodeService.getEditor(project); - if (null != editor) { - editor.getSelectionModel().removeSelection(); - } - }); - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/RequestHandler.java b/athena-all/src/main/java/run/mone/m78/ip/listener/RequestHandler.java deleted file mode 100644 index b9ebd0c75..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/listener/RequestHandler.java +++ /dev/null @@ -1,12 +0,0 @@ -package run.mone.m78.ip.listener; - -import org.cef.handler.CefRequestHandlerAdapter; - -/** - * @author goodjava@qq.com - * @date 2023/11/22 18:40 - */ -public class RequestHandler extends CefRequestHandlerAdapter { - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/listener/TreeMouseClickedListener.java b/athena-all/src/main/java/run/mone/m78/ip/listener/TreeMouseClickedListener.java deleted file mode 100644 index d926fc028..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/listener/TreeMouseClickedListener.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.listener; - -import com.intellij.ide.BrowserUtil; -import run.mone.m78.ip.bo.SpiderUrl; -import run.mone.m78.ip.service.ImageService; -import run.mone.m78.ip.service.MusicService; - -import javax.swing.*; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.TreePath; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.List; - -/** - * @Author goodjava@qq.com - * @Date 2021/11/10 10:59 - */ -public class TreeMouseClickedListener extends MouseAdapter { - - private JTree tree1; - - private JTextField textField1; - - private JPopupMenu popupMenu; - - public TreeMouseClickedListener(JTree tree1, JTextField textField1, JPopupMenu popupMenu) { - this.tree1 = tree1; - this.textField1 = textField1; - this.popupMenu = popupMenu; - } - - @Override - public void mouseClicked(MouseEvent mouseEvent) { - - if (mouseEvent.getClickCount() == 2) { - TreePath path = tree1.getPathForLocation(mouseEvent.getX(), mouseEvent.getY()); - DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); - String data = node.toString(); - System.out.println(data); - - - String text = textField1.getText(); - - if (text.equals("image")) { - new ImageService().openImage(data); - return; - } - - if (text.equals("music")) { - MusicService service = MusicService.ins(); - service.stop(); - - Object root = tree1.getModel().getRoot(); - int count = tree1.getModel().getChildCount(root); - List l = new ArrayList<>(); - for (int i = 0; i < count; i++) { - Object v = tree1.getModel().getChild(root, i); - l.add(v.toString()); - } - - service.playWithUrl(data); - return; - } - - //打开爬虫 - if (text.startsWith("spider")) { - SpiderUrl url = (SpiderUrl) node.getUserObject(); - BrowserUtil.browse(url.getUrl()); - return; - } - - } - - //中键 - if (mouseEvent.getButton() == MouseEvent.BUTTON3) { - if (textField1.getText().equals("task")) { - int x = mouseEvent.getX(); - int y = mouseEvent.getY(); - popupMenu.show(tree1, x, y); - } - } - - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/AiService.java b/athena-all/src/main/java/run/mone/m78/ip/service/AiService.java deleted file mode 100644 index 9fb373b27..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/AiService.java +++ /dev/null @@ -1,24 +0,0 @@ -package run.mone.m78.ip.service; - -import com.google.gson.JsonObject; -import run.mone.m78.ip.common.Const; -import run.mone.m78.ip.util.LabelUtils; - -/** - * @author goodjava@qq.com - * @date 2023/12/5 22:51 - */ -public class AiService { - - - //同时支持远程和本地的(本地的被限流的次数会更少) - public static JsonObject call(String req, long timeout, boolean vip) { - if (LabelUtils.open(Const.OPEN_AI_TEST)) { - return LocalAiService.call(req, timeout); - } - return ProxyAiService.call(req, timeout, vip); - - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ChatGptService.java b/athena-all/src/main/java/run/mone/m78/ip/service/ChatGptService.java deleted file mode 100644 index cb32a1ba1..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/ChatGptService.java +++ /dev/null @@ -1,31 +0,0 @@ -package run.mone.m78.ip.service; - -import com.intellij.openapi.actionSystem.AnActionEvent; -import run.mone.m78.ip.common.Context; -import lombok.extern.slf4j.Slf4j; - -/** - * @author goodjava@qq.com - * @date 2023/3/11 21:36 - *

- * 在editor中生成代码的都走这里了 - */ -@Slf4j -public class ChatGptService extends AbstractService { - - - @Override - public void execute(Context context, AnActionEvent e) { - String content = context.getContent(); - if (null != e) { - context.setProject(e.getProject()); - } - if (!(content.startsWith("//"))) { - next(context, e); - return; - } - PromptService.generateMethod(e.getProject(), content); - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/CodeService.java b/athena-all/src/main/java/run/mone/m78/ip/service/CodeService.java deleted file mode 100644 index 484d72e19..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/CodeService.java +++ /dev/null @@ -1,861 +0,0 @@ -package run.mone.m78.ip.service; - -import com.google.common.collect.Maps; -import com.google.gson.Gson; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.editor.*; -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.*; -import com.intellij.psi.javadoc.PsiDocComment; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.util.PsiTreeUtil; -import run.mone.m78.ip.bo.ClassInfo; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.MessageConsumer; -import run.mone.m78.ip.bo.ProxyAsk; -import run.mone.m78.ip.common.Context; -import run.mone.m78.ip.util.EditorUtils; -import run.mone.m78.ip.util.ImportUtils; -import run.mone.m78.ip.util.PsiClassUtils; -import run.mone.m78.ip.util.UltramanConsole; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import okhttp3.Response; -import org.apache.commons.compress.utils.Lists; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.maven.model.Dependency; -import org.apache.maven.model.Model; -import org.apache.maven.model.io.xpp3.MavenXpp3Reader; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import run.mone.ultraman.common.ImportCode; - -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.function.BiConsumer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -/** - * @author goodjava@qq.com - */ -@Slf4j -public class CodeService extends AbstractService { - - private static Gson gson = new Gson(); - - /** - * 打个某个指定的class - * - * @param project - * @param className - */ - public static PsiClass openJavaClass(Project project, String className) { - return null; - } - - - public static PsiClass[] getClassesInPackage(Project project, String packageName) { - return null; - } - - - /** - * 移动到方法的开头,且插入空行 - * Navigate to the beginning of the method and insert a blank line. - * - * @param project - */ - public static void moveToMethodAndInsertLine(Project project) { - - } - - public static String getMethodAndLineNumbers(PsiMethod method) { - return ""; - } - - public static String getClassName(PsiClass psiClass) { - return ""; - } - - - private static boolean readCodeContinue(String lineCode) { - return lineCode.trim().startsWith("//") || lineCode.trim().startsWith("/*") - || lineCode.trim().startsWith("*") || lineCode.trim().startsWith("*/"); - } - - public static String getClassAndLineNumbers(PsiClass psiClass) { - return ""; - } - - public static void addField(Project project, Document document, PsiClass psiClass, String code, String name) { - - } - - /** - * 添加方法 - * - * @param project - * @param code - */ - public static void addMethod(Project project, String code) { - - } - - - public static void insertCode(Project project, String code) { - } - - public static void insertCode(Project project, String code, boolean enter) { - } - - - /** - * 添加 import list - * - * @param project - * @param importStrList - */ - @SneakyThrows - public static void addImport(Project project, List importStrList) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - addImport(project, editor, importStrList); - } - - - public static void addImport(Project project, Editor editor, List importStrList) { - ImportUtils.addImport(project, editor, importStrList); - } - - - public static PsiClass createPsiClass(PsiElementFactory factory, String className) { - return ImportUtils.createPsiClass(factory, className); - } - - - /** - * 根据需求直接生成方法 - * - * @param project - * @param prompt - */ - public static void generateMethod(Project project, String prompt) { - } - - /** - * 向方法中添加语句 - * - * @param project - * @param code - */ - public static void addStatementToMethod(Project project, String code) { - - } - - /** - * 把代码写入Idea Editor - * - * @param project - * @param editor - * @param code - */ - public static void writeCode2(Project project, Editor editor, String code) { - writeCode4(project, editor, code, true); - } - - public static void writeCode4(Project project, Editor editor, String code, boolean appendT) { - - } - - public static void moveCaretToEndOfLine(Editor editor) { - Document document = editor.getDocument(); - CaretModel caretModel = editor.getCaretModel(); - int lineNumber = document.getLineNumber(caretModel.getOffset()); - int lineEndOffset = document.getLineEndOffset(lineNumber); - caretModel.moveToOffset(lineEndOffset); - } - - private static boolean isFirstColumn(int offset, Editor editor) { - int lineNumber = editor.getDocument().getLineNumber(offset); - int lineStartOffset = editor.getDocument().getLineStartOffset(lineNumber); - boolean isFirstColumn = (offset - lineStartOffset) == 0; - return isFirstColumn; - } - - - public static void writeCode3(Project project, String code) { - UltramanConsole.append(project, code, false); - } - - - public static Pair lineAndColumnNum(Document document, int offset) { - int lineNumber = document.getLineNumber(offset) + 1; - int columnNumber = offset - document.getLineStartOffset(lineNumber - 1); - return Pair.of(lineNumber, columnNumber); - } - - - /** - * 移动到指定行号 - * - * @param project - * @param lineNumber - */ - public static void moveLine(Project project, int lineNumber) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - LogicalPosition position = new LogicalPosition(lineNumber - 1, 0); // 创建逻辑位置对象 - editor.getCaretModel().moveToLogicalPosition(position); // 将光标移动到指定行 - } - - - /** - * 关闭当前Editor - * - * @param project - */ - public static void closeEditor(Project project) { - EditorUtils.closeEditor(project); - } - - /** - * 格式化当前代码 - */ - public static void formatCode(Project project) { - if (null == project) { - return; - } - } - - @Nullable - public static Project deleteCode(@NotNull Editor editor) { - return null; - } - - - /** - * 删除指定行 - * - * @param project - * @param lineToDelete - */ - public static void deleteLine(Project project, int lineToDelete) { - } - - - /** - * 返回所有method - * - * @param project - * @return - */ - public static List methods(Project project) { - Editor editor = getEditor(project); - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - PsiElement elementAtCaret = psiFile.findElementAt(editor.getCaretModel().getOffset()); - PsiClass currentPsiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); - return Arrays.stream(currentPsiClass.getAllMethods()).map(it -> it.getName()).collect(Collectors.toList()); - } - - - /** - * 通过module查询会快点 - * - * @param project - * @param module - * @param name - * @return - */ - public static PsiClass getPsiClass(Project project, Module module, String name) { - PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(name, GlobalSearchScope.moduleScope(module)); - return psiClass; - } - - - public static List methods(PsiClass psiClass) { - return Arrays.stream(psiClass.getMethods()).filter(it -> it.getModifierList().hasModifierProperty("public")).map(it -> it.getName()).collect(Collectors.toList()); - } - - - public static List fields(Project project) { - Editor editor = getEditor(project); - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - PsiElement elementAtCaret = psiFile.findElementAt(editor.getCaretModel().getOffset()); - PsiClass currentPsiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); - return Arrays.stream(currentPsiClass.getAllFields()).map(it -> it.getName()).collect(Collectors.toList()); - } - - public static PsiMethod getMethod(Project project) { - return null; - } - - public static String getMethodCode(Project project) { - return ApplicationManager.getApplication().runReadAction((Computable) () -> getMethod(project).getText()); - } - - public static PsiField getPsiField(Project project) { - return null; - } - - - public static boolean isTextSelected(Editor editor) { - return editor.getSelectionModel().hasSelection(); - } - - public static String getSelectedText(Editor editor) { - if (isTextSelected(editor)) { - SelectionModel selectionModel = editor.getSelectionModel(); - String selectedText = selectionModel.getSelectedText(); - return selectedText; - } - return ""; - } - - - public static PsiElement getSelectedPsiMethod(Editor editor, PsiFile psiFile) { - SelectionModel selectionModel = editor.getSelectionModel(); - int start = selectionModel.getSelectionStart(); - int end = selectionModel.getSelectionEnd(); - for (int i = start; i < end; i++) { - PsiElement element = psiFile.findElementAt(i); - @Nullable PsiMethod pm = PsiTreeUtil.getParentOfType(element, PsiMethod.class); - if (null != pm) { - return pm; - } - } - return null; - } - - public static PsiMethod getPsiMethodWithLineNum(Project project, Document document, int lineNum) { - return null; - } - - public static PsiField getPsiFieldWithLineNum(Project project, Document document, int lineNum) { - return ApplicationManager.getApplication().runReadAction((Computable) () -> { - @Nullable PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); - int start = document.getLineStartOffset(lineNum - 1); - int end = document.getLineEndOffset(lineNum - 1); - for (int i = start; i < end; i++) { - PsiElement element = psiFile.findElementAt(i); - @Nullable PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class); - if (null != field) { - return field; - } - } - return null; - }); - } - - - public static PsiClass getPsiClassWithLineNum(Project project, Document document, int lineNum) { - return ApplicationManager.getApplication().runReadAction((Computable) () -> { - @Nullable PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); - int start = document.getLineStartOffset(lineNum - 1); - int end = document.getLineEndOffset(lineNum - 1); - for (int i = start; i < end; i++) { - PsiElement element = psiFile.findElementAt(i); - @Nullable PsiClass pm = PsiTreeUtil.getParentOfType(element, PsiClass.class); - if (null != pm) { - return pm; - } - } - return null; - }); - - } - - - public static TextRange getTextRange(Project project, final Class clazz) { - Editor editor = getEditor(project); - CaretModel caretModel = editor.getCaretModel(); - int offset = caretModel.getOffset(); - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - PsiElement elementAtCaret = psiFile.findElementAt(offset); - - while (true) { - if (elementAtCaret.getClass().equals(clazz)) { - return elementAtCaret.getTextRange(); - } - elementAtCaret = elementAtCaret.getParent(); - if (null == elementAtCaret) { - return null; - } - } - } - - public static String getText(Project project, Class clazz) { - Editor editor = getEditor(project); - CaretModel caretModel = editor.getCaretModel(); - int offset = caretModel.getOffset(); - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - PsiElement elementAtCaret = psiFile.findElementAt(offset); - PsiElement element = PsiTreeUtil.getParentOfType(elementAtCaret, clazz); - return element.getText(); - } - - public static TextRange getParentTextRange(Project project) { - Editor editor = getEditor(project); - CaretModel caretModel = editor.getCaretModel(); - int offset = caretModel.getOffset(); - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - return psiFile.findElementAt(offset).getParent().getParent().getTextRange(); - } - - - public static PsiClass getPsiClass(Project project) { - Editor editor = getEditor(project); - if (null == editor) { - return null; - } - CaretModel caretModel = editor.getCaretModel(); - int offset = caretModel.getOffset(); - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - PsiElement elementAtCaret = psiFile.findElementAt(offset); - PsiClass psiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); - return psiClass; - } - - - public static PsiElement getParentOfType(Project project, Class clazz) { - Editor editor = getEditor(project); - if (null == editor) { - return null; - } - CaretModel caretModel = editor.getCaretModel(); - int offset = caretModel.getOffset(); - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - PsiElement elementAtCaret = psiFile.findElementAt(offset); - PsiElement res = PsiTreeUtil.getParentOfType(elementAtCaret, clazz); - return res; - } - - - public static PsiClass getPsiClass2(Project project) { - Editor editor = getEditor(project); - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - PsiClass psiClass = Arrays.stream(psiFile.getChildren()).filter(it -> it instanceof PsiClass).map(it -> (PsiClass) it).findFirst().get(); - return psiClass; - } - - - public static PsiMethod getMethod(PsiClass psiClass, String methodName) { - PsiMethod[] methods = psiClass.findMethodsByName(methodName, false); - return methods[0]; - } - - - public static Map getLineContentsAndNumbersForMethod(PsiMethod method) { - return Maps.newHashMap(); - } - - - public static String getClassText(Project project) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - return editor.getDocument().getText(); - } - - public static String getClassText2(Project project) { - return ""; - } - - - /** - * 根据prompt删除注解 - * - * @param project - */ - public static void removeComments(Project project) { - } - - - public static void createEmptyClass(Project project, String moduleName, String packageName, String className) { - createEmptyClass(project, moduleName, packageName, className, false); - } - - /** - * 创建空的类 - * - * @param project - * @param packageName - * @param className - */ - public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath) { - PsiClassUtils.createEmptyClass(project, moduleName, packageName, className, testPath); - } - - - public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath, boolean isInterface) { - PsiClassUtils.createEmptyClass(project, moduleName, packageName, className, testPath, false, null, isInterface); - } - - - public static void createEmptyClass(Project project, String moduleName, String packageName, String className, boolean testPath, List annoList) { - PsiClassUtils.createEmptyClass(project, moduleName, packageName, className, testPath, annoList); - } - - - public static PsiDirectory getSourceDirectory(Project project, String moduleName, boolean testPath) { - return PsiClassUtils.getSourceDirectory(project, moduleName, testPath); - } - - public static PsiDirectory getSourceDirectory(Project project, boolean testPath, String packagePath) { - return PsiClassUtils.getSourceDirectory(project, testPath, packagePath); - } - - public static PsiDirectory getSourceDirectory(Project project) { - return PsiClassUtils.getSourceDirectory(project, "", false); - } - - - public static List getClassByServiceAnno(Project project, String anno) { - return null; - } - - private static List getAllJavaFiles(PsiDirectory dir) { - return null; - } - - - /** - * 创建包路径 - * - * @param project - * @param packageName - */ - public static void createPackage(Project project, String packageName) { - - } - - public static List listMethodInfo(String clazz) { - return Lists.newArrayList(); - } - - /** - * 生成一个moon demo的handler - * - * @param project - */ - public static void generateMoonHandler(Project project) { - - } - - /** - * 获取当前类的package 路径 - * - * @param project - * @return 包路径 - */ - public static String getPackagePath(Project project) { - Editor editor = getEditor(project); - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - PsiElement elementAtCaret = psiFile.findElementAt(editor.getCaretModel().getOffset()); - // 获取最近的PsiClass - PsiClass currentPsiClass = PsiTreeUtil.getParentOfType(elementAtCaret, PsiClass.class); - PsiJavaFile psiJavaFile = (PsiJavaFile) currentPsiClass.getContainingFile(); - PsiPackage psiPackage = JavaPsiFacade.getInstance(currentPsiClass.getProject()).findPackage(psiJavaFile.getPackageName()); - return psiPackage.getQualifiedName(); - } - - - @Override - public void execute(Context context, AnActionEvent e) { - this.next(context, e); - } - - public static void addClassAnno(Project project, PsiClass psiClass, List annoList) { - - } - - /** - * 删除这个编辑器中的所有内容 - * - * @param project - */ - public static void deleteCode(Project project) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - WriteCommandAction.runWriteCommandAction(project, () -> { - editor.getDocument().setText(""); - }); - Caret caret = editor.getCaretModel().getPrimaryCaret(); - caret.moveToOffset(0); - } - - public static void deleteTextRange(Project project, TextRange range) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - WriteCommandAction.runWriteCommandAction(project, () -> { - Document document = editor.getDocument(); - document.deleteString(range.getStartOffset(), range.getEndOffset()); - PsiDocumentManager.getInstance(project).commitDocument(document); - }); - } - - - public static boolean isClass(String text) { - if (text.contains(" class ")) { - return true; - } - return false; - } - - public static boolean isPrivateField(String text) { - if (text.contains("private") && text.contains(";")) { - return true; - } - return false; - } - - - private static Integer getNumFromStr(String str) { - Pattern pattern = Pattern.compile("\\d+"); - Matcher matcher = pattern.matcher(str); - String lineNumber = "0"; - if (matcher.find()) { - lineNumber = matcher.group(); - } - return Integer.valueOf(lineNumber); - } - - /** - * 通过chatgpt生成代码,然后插入编辑器中 - * - * @param project - * @param context - * @param prompt - */ - public static void generateCodeWithAi(Project project, String context, String[] prompt, BiConsumer consumer) { - - } - - public static void generateCodeWithAi2(Project project, String promptName, String[] pramas, BiConsumer consumer) { - generateCodeWithAi3(project, promptName, pramas, Maps.newHashMap(), consumer); - } - - - public static void generateCodeWithAi3(Project project, String promptName, String[] pramas, Map paramMap, BiConsumer consumer) { - generateCodeWithAi4(project, promptName, pramas, paramMap, consumer, new MessageConsumer()); - } - - - public static void generateCodeWithAi4(Project project, String promptName, String[] pramas, Map paramMap, BiConsumer consumer, MessageConsumer messageConsumer) { - generateCodeWithAi5(GenerateCodeReq.builder().promptName(promptName).project(project).build(), project, promptName, pramas, paramMap, consumer, messageConsumer); - } - - - @SneakyThrows - public static String call(String promptName, Map paramMap) { - return ""; - } - - - public static void generateCodeWithAi5(GenerateCodeReq req, Project project, String promptName, String[] pramas, Map paramMap, BiConsumer consumer, MessageConsumer messageConsumer) { - - } - - public static void setModelAndDebug(Project project, ProxyAsk pa, Map paramMap, GenerateCodeReq req) { - } - - private static int getCodeSize(Map paramMap) { - return 1; - } - - - @NotNull - private static String getErrorMessage(Throwable t, Response response) { - String message = ""; - if (null != response) { - message = response.message(); - if (StringUtils.isNotEmpty(message)) { - message = "错误原因:" + message; - } else { - message = ""; - } - } - if (null != t) { - message += t.getMessage(); - } - return message; - } - - - public static void generateCodeWithAi(Project project, String context, String[] prompt) { - generateCodeWithAi(project, context, prompt, (p, code) -> { - writeCode(p, code); - }); - } - - - /** - * 直接插入代码 - * - * @param project - * @param str - */ - public static void writeCode(Project project, String str) { - - } - - - /** - * 选中一个方法 - * - * @param project - */ - public static PsiMethod selectMethod(Project project) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - if (null == editor) { - return null; - } - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - if (psiFile == null) { - return null; - } - PsiElement element = psiFile.findElementAt(editor.getCaretModel().getOffset()); - PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class); - return method; - } - - public static void deleteMethod(Project project, PsiMethod method) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - if (null == editor) { - return; - } - - if (null == method) { - return; - } - Document document = editor.getDocument(); - int startOffset = method.getTextRange().getStartOffset(); - - editor.getCaretModel().getPrimaryCaret().moveToOffset(startOffset); - - int endOffset = method.getTextRange().getEndOffset(); - WriteCommandAction.runWriteCommandAction(project, () -> document.deleteString(startOffset, endOffset)); - } - - public static void deletePsiClass(Project project, PsiClass psiClass) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - Document document = editor.getDocument(); - int startOffset = psiClass.getTextRange().getStartOffset(); - editor.getCaretModel().getPrimaryCaret().moveToOffset(startOffset); - int endOffset = psiClass.getTextRange().getEndOffset(); - WriteCommandAction.runWriteCommandAction(project, () -> document.deleteString(startOffset, endOffset)); - } - - - public static Editor getEditor(Project project) { - return EditorUtils.getEditor(project); - } - - public static Document getDocument(Project project) { - return getEditor(project).getDocument(); - } - - - /** - * 添加空行 - * - * @param project - * @param document - * @param num - */ - public static void addLineBreak(Project project, Document document, int lineNum, int num) { - - } - - public static List getClassList(Project project, String end, String mn) { - return null; - } - - - private static String findPomDependencies(String basePath, String groupId, String artifactId, String version) throws IOException { - File baseDir = new File(basePath); - String[] extensions = {"xml"}; - boolean recursive = true; - - Collection pomFiles = FileUtils.listFiles(baseDir, extensions, recursive); - for (File pomFile : pomFiles) { - try { - MavenXpp3Reader reader = new MavenXpp3Reader(); - Model model = reader.read(new FileReader(pomFile)); - List dependencies = model.getDependencies(); - for (Dependency dependency : dependencies) { - if (dependency.getGroupId().equals(groupId) && - dependency.getArtifactId().equals(artifactId) && - dependency.getVersion().equals(version)) { - // 找到了指定的依赖项 - return "找到了"; - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - return "没找到"; - } - - - /** - * 获取方法的注释 - * - * @param psiMethod - * @return - */ - public static String getMethodComment(PsiMethod psiMethod) { - PsiDocComment comment = psiMethod.getDocComment(); - if (comment != null) { - return comment.getText(); - } - return null; - } - - /** - * 获取属性的注释 - * - * @param psiField - * @return - */ - public static String getFieldComment(PsiField psiField) { - PsiDocComment comment = psiField.getDocComment(); - if (comment != null) { - return comment.getText(); - } - return ""; - } - - public static ImportCode createClassAndAddEmptyLine(Project project, String module, String packageName, String className, String classNameSuffix, boolean isTestClass, boolean isInterface) { - return null; - } - - private static void addEmptyLine(Project project, PsiClass openJavaClass, Editor editor) { - PsiMethod @NotNull [] methods = openJavaClass.getMethods(); - int offset = 0; - if (0 == methods.length) { - offset = openJavaClass.getTextRange().getEndOffset() - 3; - } else { - PsiMethod psiMethod = methods[methods.length - 1]; - offset = psiMethod.getTextRange().getEndOffset(); - } - editor.getCaretModel().moveToOffset(offset); - CodeService.writeCode2(project, editor, "\n"); - - } - - - @Override - public void next(Context context, AnActionEvent e) { - super.next(context, e); - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/DocumentService.java b/athena-all/src/main/java/run/mone/m78/ip/service/DocumentService.java deleted file mode 100644 index d2e1246e1..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/DocumentService.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.service; - -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.diagnostic.Logger; -import org.apache.commons.lang3.tuple.Pair; - -/** - * @Author goodjava@qq.com - * @Date 2021/11/6 12:08 - */ -public class DocumentService { - - private static final Logger log = Logger.getInstance(DocumentService.class); - - /** - * 用ide打开文件 - * - * @param name - * @param text - */ - public void open(String name, String text) { - log.info("open file"); - } - - /** - * 获取文件内容和文件名(content,fileName) - * - * @param anActionEvent - * @return - */ - public Pair getContent(AnActionEvent anActionEvent) { - log.info("get content"); - return null; - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/LocalAiService.java b/athena-all/src/main/java/run/mone/m78/ip/service/LocalAiService.java deleted file mode 100644 index 4a9b83b76..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/LocalAiService.java +++ /dev/null @@ -1,139 +0,0 @@ -package run.mone.m78.ip.service; - -import com.google.common.collect.Lists; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.intellij.openapi.project.Project; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.tuple.Pair; -import run.mone.m78.ip.bo.AiMessage; -import run.mone.m78.ip.bo.chatgpt.*; -import run.mone.m78.ip.common.Const; -import run.mone.m78.ip.util.ResourceUtils; -import run.mone.openai.StreamListener; -import run.mone.ultraman.common.GsonUtils; - -import java.io.File; -import java.util.List; - -/** - * @author goodjava@qq.com - * @date 2023/11/23 13:56 - *

- * 这个类允许你本地直连chatgpt(如果是国内的网络需要设置open_ai_proxy) - */ -@Slf4j -public class LocalAiService { - - - private static String getOpenAiUrl() { - String url = ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_PROXY, ""); - return url; - } - - - /** - * 调用chatgpt的语音翻译(你需要有chatgpt的账号) - * - * @param file - * @return - */ - @SneakyThrows - public static Pair callChatgptTranscriptions(File file) { - return Pair.of(200, ""); - } - - - /** - * 把文字转成语音 - * - * @param req - * @return - */ - @SneakyThrows - public static Pair speech(SpeechReq req) { - return null; - } - - - //多模态调用(支持图片) - public static String vision(VisionReq req) { - return ""; - } - - - public static JsonObject call(List messageList) { - Completions completions = Completions.builder() - .stream(false) - .response_format(Format.builder().build()).messages(messageList).build(); - String req = GsonUtils.gson.toJson(completions); - return call(req); - } - - - public static JsonObject call(String req) { - return call(req, 5000); - } - - //这个会直接调用chatgpt - @SneakyThrows - public static JsonObject call(String req, long timeout) { - return null; - } - - - //直接问问题(直接调用chatgpt) - public static void completions(String req, StreamListener sl) { - } - - - private static String parse(String data) { - log.info(data); - if (data.equals("[DONE]")) { - return ""; - } - return ""; - } - - private static JsonObject parseJson(String data) { - log.info("data:{}", data); - JsonObject obj = GsonUtils.gson.fromJson(data, JsonObject.class); - JsonArray choices = obj.getAsJsonArray("choices"); - return GsonUtils.gson.fromJson(choices.get(0).getAsJsonObject().getAsJsonObject("").get("").getAsString(), JsonObject.class); - } - - //本地直接调用chatgpt,单条提问 - public static void localCall(Project project, String prompt) { - localCall(project, Lists.newArrayList(Message.builder().content(prompt).role("user").build()), false, 0); - } - - - public static void localCall(String projectName, boolean code) { - } - - - public static void localCall(Project project, List messageList, boolean code, int num) { - } - - - public static List getLastElements(List list, int num) { - return null; - } - - private static void chat(Project project, boolean code, List newMessageList, String projectName, String id) { - } - - - //调用ai proxy(进行聊天) - private static void aiProxyChat(Project project, List newMessageList) { - - } - - //每次都只发一部分(发送到右侧 athena) - private static void sendMsg(AiMessage message, String projectName) { - - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/MusicService.java b/athena-all/src/main/java/run/mone/m78/ip/service/MusicService.java deleted file mode 100644 index a36a9ab2f..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/MusicService.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.service; - -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.application.ApplicationManager; -import run.mone.m78.ip.action.ActionEnum; -import run.mone.m78.ip.common.ApiCall; -import run.mone.m78.ip.common.Context; -import run.mone.m78.ip.common.Mp3PlayerV2; -import run.mone.m78.ip.common.NotificationCenter; -import run.mone.m78.ip.common.Safe; -import org.apache.commons.lang.StringUtils; - -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -/** - * @Author goodjava@qq.com - * @Date 2021/11/6 11:46 - */ -public class MusicService extends AbstractService { - - private List list = new ArrayList<>(); - - private int index; - - private String musicUrl; - - public void setList(List list) { - this.list = list; - } - - private static final class LazyHolder { - private static MusicService ins = new MusicService(); - } - - public static MusicService ins() { - return LazyHolder.ins; - } - - private MusicService() { - Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> { - if (StringUtils.isNotEmpty(musicUrl)) { - if (Mp3PlayerV2.ins().isComplete()) { - play(musicUrl); - } - } - }, 0, 1, TimeUnit.SECONDS); - } - - public synchronized void play(String t) { - musicUrl = t; - ApplicationManager.getApplication().invokeLater(() -> { - Safe.run(() -> { - if (StringUtils.startsWith(t, ActionEnum.diga.name() + ":")) { - String url = new ApiCall().callIt(ApiCall.MUSIC_API, t.replaceFirst(ActionEnum.diga.name() + ":", "") + ".mp3"); - InputStream input = new URL(url).openStream(); - Mp3PlayerV2.ins().play(input); - return; - } - String url = new ApiCall().callOne(ApiCall.MUSIC_API); - NotificationCenter.notice("music:" + url); - InputStream input = new URL(url).openStream(); - //这里会启用一个新的线程 - Mp3PlayerV2.ins().play(input); - }); - }); - } - - public void playWithUrl(String url) { - Safe.run(() -> { - InputStream input = new URL(url).openStream(); - Mp3PlayerV2.ins().play(input); - }); - } - - public synchronized void stop() { - this.musicUrl = ""; - Safe.run(() -> Mp3PlayerV2.ins().close()); - } - - @Override - public void execute(Context context, AnActionEvent e) { - String content = context.getContent(); - if (content.equals(ActionEnum.diga.name()) || StringUtils.startsWith(content, ActionEnum.diga.name() + ":")) { - play(content); - return; - } - - if (content.equals(ActionEnum.diga_stop.name())) { - stop(); - return; - } - - this.next(context, e); - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/PromptService.java b/athena-all/src/main/java/run/mone/m78/ip/service/PromptService.java deleted file mode 100644 index 01befe325..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/PromptService.java +++ /dev/null @@ -1,356 +0,0 @@ -package run.mone.m78.ip.service; - -import com.google.gson.Gson; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiMethod; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.Message; -import run.mone.m78.ip.bo.PromptContext; -import run.mone.m78.ip.bo.RobotContext; -import run.mone.m78.ip.util.HintUtils; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; -import java.util.Map; - -import static run.mone.m78.ip.util.PromptUtils.*; - -/** - * @author goodjava@qq.com - * @author baoyu - * @date 2023/5/11 21:53 - *

- * 这个类主要处理Prompt在Idea中的落地(写入编辑器) - */ -@Slf4j -public class PromptService { - - private static Gson gson = new Gson(); - - /** - * 动态执行 - * - * @param req - * @return - */ - public static String dynamicInvoke(GenerateCodeReq req) { - setReq(req); - switch (req.getPromptType()) { - case createClass -> createClass(req.getProject(), req.getModule().getName(), req.getPromptName()); - case createClass4 -> createClass4(req); - case createMethod -> createMethod(req); - case createMethod2 -> createMethod2(req); - case comment -> addComment(req); - case lineByLineComment -> lineByLineCommentOrCode(req.getPromptName(), req); - case createFile -> createFile(req.getPromptName(), req.getFileName(), req); - case modifyClass -> updateClass(req); - case modifyMethod -> updateMethod(req); - case select -> select(req, req.getProject(), req.getModule(), req.getPromptInfo()); - case removeComment -> removeComment(req.getProject()); - case showInfo -> showInfo(req); - case repleaceSelectContent -> repleaceSelectContent(req); - case testPrompt -> testPrompt(req); - case checkPomVersion -> checkPomVersion(req); - case generateBootStrapAnno -> generateAnnoForBootStrap(req.getPromptName(), req.getProject()); - case inlayHint -> inlayHint(req); - case genBizMethodCode -> genBizMethodCode(req); - case generateMethod -> generateMethod(req, req.getProject(), ""); - case bot -> RobotService.bot(req); - case generateMiapiMethod -> generateMiapiMethod(req); - case generateInterface -> generateInterface(req); - case question -> question(req); - case createClass2 -> - createClass2(req.getProject(), req.getPromptName(), req.getShowDialog(), req.getParam()); - default -> { - return "UnSupport"; - } - } - return "ok"; - } - - private static void createClass4(GenerateCodeReq req) { - - } - - //ai会向你提问(绝大部分分多步的操作,ai问你更合适) - private static void question(GenerateCodeReq req) { - - } - - //后边代码尽量用这里获取的内容,editor中的内容放入到req中,避免后边的再次获取 - public static void setReq(GenerateCodeReq req) { - - } - - private static String getClassPackage(String qualifiedName) { - int lastDotIndex = qualifiedName.lastIndexOf('.'); - if (lastDotIndex >= 0) { - return qualifiedName.substring(0, lastDotIndex); - } - return ""; - } - - - //获取编辑器的注释信息 - private static String getComment(Editor editor) { - return getComment(editor, "//biz:"); - } - - private static String getComment(Editor editor, String str) { - return ""; - } - - - /** - * 生成业务方法 - * - * @param req - */ - public static void genBizMethodCode(GenerateCodeReq req) { - - } - - private static String addCode(GenerateCodeReq req, Map m, PromptContext context) { - return ""; - } - - - //添加上下文信息到映射中 - private static void addContext(GenerateCodeReq req, Map m, PromptContext promptContext) { - - } - - public static String getResourceFromAi(Project project, Map m, PromptContext promptContext, List resourceCode) { - return ""; - } - - - public static void inlayHint(GenerateCodeReq req) { - - } - - /** - * 测试prompt的接口 - * - * @param req - */ - private static void testPrompt(GenerateCodeReq req) { - - } - - private static void repleaceSelectContent(GenerateCodeReq req) { - - } - - /** - * 在聊天窗口显示信息 - * - * @param req - */ - public static void showInfo(GenerateCodeReq req) { - - } - - - public static void generateMethod(Project project, String content) { - - } - - - //创建方法都收口在这里了 - public static void generateMethod(GenerateCodeReq req) { - - } - - private static void initAiReqMap(GenerateCodeReq req, Map aiReqMap) { - - } - - private static void analysisScope(GenerateCodeReq req, PromptContext context) { - - } - - private static void addField(GenerateCodeReq req, Map map) { - - } - - private static void addClass(GenerateCodeReq req, Map map, PromptContext context) { - - } - - - public static String getCode(GenerateCodeReq req, PromptContext context) { - return ""; - } - - /** - * 删除逐行注释 - * - * @param project - */ - private static void removeComment(Project project) { - PsiMethod psiMethod = CodeService.getMethod(project); - Editor editor = CodeService.getEditor(project); - if (null == psiMethod) { - HintUtils.show(editor, Message.selectMethodMsg, true); - return; - } - PsiMethodUtils.deleteCommentsFromMethod(project, psiMethod, comment -> comment.getText().startsWith("//Athena:")); - } - - - - /** - * 生成方法(在edit中) - * - * @param project - * @param text - */ - public static void generateMethod(GenerateCodeReq req, Project project, String text) { - - } - - - private static void createMethod(GenerateCodeReq req) { - - } - - /** - * stream样式添加注释 - */ - public static void comment2(RobotContext context, GenerateCodeReq req) { - } - - /** - * 给出一些修改代码的意见 - */ - public static void modifyCodeSuggest(RobotContext context, GenerateCodeReq req) { - } - - /** - * 需要导入那些依赖 - * - * @param context - * @param req - */ - public static void getImport(RobotContext context, GenerateCodeReq req) { - req.setPromptName("get_import"); - addComment(req); - } - - - /** - * 根据类生成sql建表文件 - * - * @param context - * @param req - */ - public static void createTabStatement(RobotContext context, GenerateCodeReq req) { - createFile("create_tab_statement", "tmp.sql", req); - } - - /** - * 把class转换为json文件 - * - * @param context - * @param req - */ - public static void classJson(RobotContext context, GenerateCodeReq req) { - createFile("class_json", "tmp.json", req); - } - - - /** - * 根据业务需求直接生成代码 - * - * @param context - * @param req - */ - public static void bizCodeGen(RobotContext context, GenerateCodeReq req) { - } - - - - - /** - * 创建方法2 - *

- * 会打开两个表单 - * 1.填参数 - * 2.选中类和方法 - * - *

- * 选择类和方法,然后插入代码 - *

- * 可以用来生成Controller中的方法 - * - * @param req - */ - public static void createMethod2(GenerateCodeReq req) { - - - } - - public static void addFields(Project project, String serviceName, String shortServiceName, PsiClass psiClass, Editor editor) { - } - - public static void addImports(GenerateCodeReq req, Project project, String serviceName, String reqClass, Editor editor) { - } - - public static void addImports(GenerateCodeReq req, Project project, String serviceName, String reqClass, Editor editor, boolean unitTest, boolean resource, String unitVersion) { - - } - - /** - * 给interface中添加方法(返回值可能被包装要注意) - * - * @param psiClass - */ - private static void addMethodToInterface(GenerateCodeReq req, PsiClass psiClass, PsiMethod pm, PsiClass reqClass) { - - } - - private static void modifyReq(GenerateCodeReq req, PsiMethod pm, String reqClass) { - - } - - private static void setLabels(GenerateCodeReq req, Map map) { - - } - - - /** - * 生成使用中间件的代码 - * - * @param context - * @param req - */ - public static void midCodeGen(RobotContext context, GenerateCodeReq req) { - } - - /** - * 逐行注释 - * - * @param context - * @param req - */ - public static void cc(RobotContext context, GenerateCodeReq req) { - } - - /** - * fix(问题修复,给出来的是建议) - * - * @param context - * @param req - */ - public static void fix(RobotContext context, GenerateCodeReq req) { - } - - //暂时只生成接口引入 - public static void generateMiapiMethod(GenerateCodeReq req) { - - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/ProxyAiService.java b/athena-all/src/main/java/run/mone/m78/ip/service/ProxyAiService.java deleted file mode 100644 index 016ebfd93..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/ProxyAiService.java +++ /dev/null @@ -1,41 +0,0 @@ -package run.mone.m78.ip.service; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import run.mone.m78.ip.bo.chatgpt.Message; -import lombok.extern.slf4j.Slf4j; - -import java.util.List; - -/** - * @author goodjava@qq.com - * @date 2023/12/5 22:13 - */ -@Slf4j -public class ProxyAiService { - - - private static Gson gson = new Gson(); - - public static JsonObject call(List messageList) { - return call(messageList, 50000); - } - - public static JsonObject call(String r, long time, boolean vip) { - String pa = "jsonStr"; - String req = gson.toJson(pa); - return call0(req, time, vip); - } - - //调用ai proxy (调用的是json接口,返回的数据一定是json格式) - public static JsonObject call0(String req, long time, boolean vip) { - return null; - } - - public static JsonObject call(List messageList, long time) { - String pa = "jsonStr"; - String req = gson.toJson(pa); - return call0(req, time, true); - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/PsiMethodUtils.java b/athena-all/src/main/java/run/mone/m78/ip/service/PsiMethodUtils.java deleted file mode 100644 index a82638d23..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/PsiMethodUtils.java +++ /dev/null @@ -1,49 +0,0 @@ -package run.mone.m78.ip.service; - -import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.project.Project; -import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; -import java.util.function.Predicate; - -/** - * @author goodjava@qq.com - * @date 2023/6/3 22:31 - */ -public class PsiMethodUtils { - - - /** - * 删除指定方法中的注释 - * - * @param psiMethod - */ - public static void deleteCommentsFromMethod(Project project, PsiMethod psiMethod, Predicate predicate) { - @NotNull Collection comments = PsiTreeUtil.collectElementsOfType(psiMethod, PsiComment.class); - WriteCommandAction.runWriteCommandAction(project, () -> { - for (PsiComment comment : comments) { - if (predicate.test(comment)) { - comment.delete(); - } - } - }); - } - - /** - * 修改方法名 - * - * @param project 项目对象 - * @param document 文档对象 - * @param method 方法对象 - * @param newName 新方法名 - */ - public static void modifyMethodName(Project project, Document document, PsiMethod method, String newName) { - - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/TestService.java b/athena-all/src/main/java/run/mone/m78/ip/service/TestService.java deleted file mode 100644 index 396b2e879..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/TestService.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.service; - -import com.intellij.openapi.actionSystem.AnActionEvent; -import lombok.extern.slf4j.Slf4j; -import run.mone.m78.ip.common.Context; - -/** - * @Author goodjava@qq.com - * @Date 2021/11/7 21:43 - */ -@Slf4j -public class TestService extends AbstractService { - @Override - public void execute(Context context, AnActionEvent e) { - String content = context.getContent(); - if (content.equals("test")) { - } - this.next(context, e); - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/TextService.java b/athena-all/src/main/java/run/mone/m78/ip/service/TextService.java deleted file mode 100644 index b3be6808a..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/TextService.java +++ /dev/null @@ -1,56 +0,0 @@ -package run.mone.m78.ip.service; - -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiFile; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.jetbrains.annotations.NotNull; - - -/** - * @author goodjava@qq.com - * @date 2023/5/17 15:46 - */ -@Slf4j -public class TextService { - - - public static void writeContent(Project project, String fileName, String moduleName, Runnable runnable) { - writeContent(project, fileName, moduleName, runnable, null); - } - - - public static String readContent(Project project, String module, String fileName) { - PsiDirectory directory = getPsiDirectory(project, module); - if (null == directory) { - return ""; - } - PsiFile file = directory.findFile(fileName); - if (null == file) { - return ""; - } - return file.getText(); - } - - - public static void writeContent(Project project, String fileName, String moduleName, Runnable runnable, String content) { - - } - - @NotNull - private static String getFileContent(String content) { - String fileContent = " "; - if (StringUtils.isNotEmpty(content)) { - fileContent = content; - } - return fileContent; - } - - - private static PsiDirectory getPsiDirectory(Project project, String moduleName) { - return null; - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/service/XmlService.java b/athena-all/src/main/java/run/mone/m78/ip/service/XmlService.java deleted file mode 100644 index c558a6fec..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/service/XmlService.java +++ /dev/null @@ -1,56 +0,0 @@ -package run.mone.m78.ip.service; - -import com.intellij.openapi.project.Project; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.maven.model.Model; -import org.apache.maven.model.io.xpp3.MavenXpp3Writer; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Map; - -/** - * @author goodjava@qq.com - * @date 2023/5/21 22:07 - */ -public class XmlService { - - /** - * 方便操纵xml,这里的作用是修改maven 中的 pom 加入依赖 - * - * @param project - * @param moduleName - * @param dependency - */ - public static void openMavenPomAndModify(Project project, String moduleName, String dependency) { - - } - - public static Pair checkPomVersion(Project project, String groupId, String artifactId, String version) { - return null; - } - - @NotNull - private static Pair insertDependency(Project project, String groupId, String artifactId, String version, Map modulePathMap) throws IOException, XmlPullParserException { - return null; - } - - private static Pair writeDependency(Model model, File pomFile) { - return null; - } - - private static String buildDependencyString(String groupId, String artifactId, String version) { - return String.format("```\n" + - "\n" + - " \t%s\n" + - " \t%s\n" + - " \t%s\n" + - "", groupId, artifactId, version); - - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.form deleted file mode 100644 index 19237e4c8..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.form +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.java deleted file mode 100644 index 29998009a..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/TestUi.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.ui; - - -import javax.swing.*; -import javax.swing.text.BadLocationException; -import javax.swing.text.Style; -import javax.swing.text.StyleConstants; -import javax.swing.text.StyledDocument; -import java.awt.*; -import java.awt.datatransfer.Clipboard; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.StringSelection; -import java.awt.datatransfer.Transferable; -import java.awt.event.*; -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; - -public class TestUi extends JDialog { - private JPanel contentPane; - private JButton buttonOK; - private JButton buttonCancel; - private JTextPane textPane1; - private JButton button1; - - public TestUi() { - setContentPane(contentPane); - setModal(true); - getRootPane().setDefaultButton(buttonOK); - - buttonOK.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - onOK(); - } - }); - - buttonCancel.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - onCancel(); - } - }); - - // call onCancel() when cross is clicked - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - onCancel(); - } - }); - - // call onCancel() on ESCAPE - contentPane.registerKeyboardAction(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - onCancel(); - } - }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); - - - init(); - button1.addActionListener(e -> { - JFileChooser jfc = new JFileChooser(); - jfc.setFileSelectionMode(JFileChooser.FILES_ONLY); - jfc.showDialog(new JLabel(), "选择"); - File file = jfc.getSelectedFile(); - if (file.isDirectory()) { - System.out.println("文件夹:" + file.getAbsolutePath()); - } else if (file.isFile()) { - System.out.println("文件:" + file.getAbsolutePath()); - } - System.out.println(jfc.getSelectedFile().getName()); - URL url = uploadFile(bucketName, jfc.getSelectedFile()); - setClipboardString(url.toString()); - }); - } - - - public static void setClipboardString(String text) { - // 获取系统剪贴板 - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - // 封装文本内容 - Transferable trans = new StringSelection(text); - // 把文本内容设置到系统剪贴板 - clipboard.setContents(trans, null); - } - - - /** - * 从剪贴板中获取文本(粘贴) - */ - public static String getClipboardString() { - // 获取系统剪贴板 - Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - - // 获取剪贴板中的内容 - Transferable trans = clipboard.getContents(null); - - if (trans != null) { - // 判断剪贴板中的内容是否支持文本 - if (trans.isDataFlavorSupported(DataFlavor.stringFlavor)) { - try { - // 获取剪贴板中的文本内容 - String text = (String) trans.getTransferData(DataFlavor.stringFlavor); - return text; - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - return null; - } - - - private void init() { - JTextPane textPane = textPane1; - textPane.setMaximumSize(new Dimension(100, 100)); - StyledDocument doc = (StyledDocument) textPane.getDocument(); - - Style style = doc.addStyle("StyleName", null); - try { - StyleConstants.setIcon(style, scaledImage("https://static.runoob.com/images/demo/demo1.jpg")); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - - try { - doc.insertString(doc.getLength(), "", style); - } catch (BadLocationException e) { - e.printStackTrace(); - } - - System.out.println(textPane1.getText()); - } - - - private ImageIcon scaledImage(String location) throws MalformedURLException { - Image image = Toolkit.getDefaultToolkit().getImage(new URL(location)); - image = image.getScaledInstance(120, 120, Image.SCALE_SMOOTH); - return new ImageIcon(image); - } - - private void onOK() { - - System.out.println(textPane1.getText()); -// fileMeta(); - -// getUrl(key); -// uploadFile(bucketName,new File("/Users/zhangzhiyong/Desktop/girl2.jpeg")); - listFile(); - } - - - String endpoint = "oss-cn-beijing.aliyuncs.com"; - String accessKeyId = ""; - String accessKeySecret = ""; - String bucketName = "datazzy"; - String key = "girl.jpeg"; - - public URL getUrl(String key) { - return null; - } - - - public void listFile() { - } - - - public URL uploadFile(String bucketName, File file) { - return null; - } - - - private void fileMeta() { - } - - - private void onCancel() { - // add your code here if necessary - dispose(); - } - - public static void main(String[] args) { - TestUi dialog = new TestUi(); - dialog.pack(); - dialog.setVisible(true); - System.exit(0); - } -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.form b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.form deleted file mode 100644 index 42d80ecbf..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.form +++ /dev/null @@ -1,99 +0,0 @@ - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.java b/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.java deleted file mode 100644 index cf20e17b7..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/ui/UltramanUi.java +++ /dev/null @@ -1,68 +0,0 @@ -package run.mone.m78.ip.ui; - -import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; - -public class UltramanUi extends JDialog { - - private JPanel contentPane; - private JButton buttonOK; - - private JPanel panel1; - private JLabel imageLabel; - private JLabel descLabel; - - - public UltramanUi() { - setContentPane(contentPane); - setModal(true); - getRootPane().setDefaultButton(buttonOK); - - buttonOK.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - onOK(); - } - }); - - // call onCancel() when cross is clicked - setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - onOK(); - } - }); - - // call onCancel() on ESCAPE - contentPane.registerKeyboardAction(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - onOK(); - } - }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); - - - ImageIcon img = new ImageIcon("/tmp/a.jpeg"); - imageLabel.setIcon(img); - imageLabel.setText(""); - this.descLabel.setText("就算化成灰,我的bug也不会放过你;所以,请相信你自己,然后,也请给我发红包"); - - } - - private void onOK() { - // add your code here - dispose(); - } - - public static void main(String[] args) { - UltramanUi dialog = new UltramanUi(); - dialog.pack(); - dialog.setVisible(true); - System.exit(0); - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/EditorUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/EditorUtils.java deleted file mode 100644 index 99a4c6896..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/util/EditorUtils.java +++ /dev/null @@ -1,149 +0,0 @@ -package run.mone.m78.ip.util; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.ScrollType; -import com.intellij.openapi.editor.SelectionModel; -import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.fileEditor.OpenFileDescriptor; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.search.FilenameIndex; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.testFramework.LightVirtualFile; -import run.mone.m78.ip.common.Const; -import org.apache.commons.lang3.StringUtils; -import org.jetbrains.annotations.NotNull; - -/** - * @author goodjava@qq.com - * @date 2023/4/18 00:13 - */ -public class EditorUtils { - - public static void scroll(Project project) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - editor.getScrollingModel().scrollToCaret(ScrollType.CENTER_DOWN); // 翻到下一页 - } - - public static String getSelectContent(Editor editor) { - return getSelectContent(editor, true); - } - - public static String getSelectContent(Editor editor, boolean selectLine) { - try { - Document document = editor.getDocument(); - final SelectionModel selectionModel = editor.getSelectionModel(); - final int start = selectionModel.getSelectionStart(); - final int end = selectionModel.getSelectionEnd(); - TextRange range = new TextRange(start, end); - String selectTxt = document.getText(range); - - //没有选中任何东西,则选中那一行 - if (StringUtils.isEmpty(selectTxt) && selectLine) { - selectionModel.selectLineAtCaret(); - final int start1 = selectionModel.getSelectionStart(); - final int end1 = selectionModel.getSelectionEnd(); - TextRange range1 = new TextRange(start1, end1); - selectTxt = document.getText(range1); - if (null != selectTxt) { - selectTxt = selectTxt.trim(); - } - } - return selectTxt; - } catch (Throwable ignore) { - return ""; - } - } - - public static Editor getEditorFromPsiClass(Project project, PsiClass psiClass) { - PsiFile psiFile = psiClass.getContainingFile(); - if (psiFile != null) { - String fileName = psiFile.getName(); - PsiFile[] files = FilenameIndex.getFilesByName(project, fileName, GlobalSearchScope.allScope(project)); - for (PsiFile file : files) { - VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile != null) { - FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); - return fileEditorManager.openTextEditor(new OpenFileDescriptor(project, virtualFile), true); - } - } - } - return null; - } - - /** - * 移动到最后一个方法的最后部 - * - * @param psiClass - * @param editor - */ - public static void moveToLastMethodEnd(PsiClass psiClass, Editor editor) { - PsiMethod @NotNull [] methods = psiClass.getMethods(); - int offset = 0; - if (methods.length == 0) { - offset = psiClass.getTextRange().getEndOffset() - 1; - } else { - PsiMethod psiMethod = methods[methods.length - 1]; - offset = psiMethod.getTextRange().getEndOffset(); - } - editor.getCaretModel().moveToOffset(offset); - } - - public static void closeEditor(Project project) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - if (null != editor) { - FileEditorManager manager = FileEditorManager.getInstance(project); - PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - manager.closeFile(psiFile.getVirtualFile()); - } - } - - public static void openEditor(Project project, String content, String name) { - VirtualFile virtualFile = new LightVirtualFile(name, content); - virtualFile.putUserData(Const.T_KEY, name); - ApplicationManager.getApplication().runWriteAction((Computable) () -> { - Document document = FileDocumentManager.getInstance().getDocument(virtualFile); - if (document != null) { - document.setText(content); - } - return FileEditorManager.getInstance(project).openFile(virtualFile, true); - }); - } - - public static Editor getEditor(Project project) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - return editor; - } - - - /** - * 获取或打开指定名称和内容的编辑器。 - * 如果已经存在打开的编辑器,则返回该编辑器,否则打开一个新的编辑器。 - * 如果打开的文件扩展名为"md",则返回该编辑器。 - * - * @param project 项目对象 - * @param name 文件名称 - * @param content 文件内容 - * @return 编辑器对象 - */ - public static Editor getOrOpenEditor(Project project, String name, String content) { - Editor editor = getEditor(project); - if (null == editor || !FileDocumentManager.getInstance().getFile(editor.getDocument()).equals("md")) { - openEditor(project, content, name); - } else { - return editor; - } - return getEditor(project); - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/GitUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/GitUtils.java deleted file mode 100644 index a3e304c15..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/util/GitUtils.java +++ /dev/null @@ -1,54 +0,0 @@ -package run.mone.m78.ip.util; - -import com.google.common.base.Joiner; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vcs.changes.ChangeListManager; -import lombok.SneakyThrows; - -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -/** - * @author goodjava@qq.com - * @date 2023/7/8 23:19 - */ -public class GitUtils { - - - /** - * 获取项目中受影响的文件名列表。 - * - * @param project 项目对象 - * @return 受影响的文件名列表 - */ - public static List getAffectedFileNames(Project project) { - ChangeListManager changeListManager = ChangeListManager.getInstance(project); - return changeListManager.getAffectedFiles().stream().map(it -> it.toString()).collect(Collectors.toList()); - } - - public static String getAffectedFileNamesStr(Project project) { - ChangeListManager changeListManager = ChangeListManager.getInstance(project); - List list = changeListManager.getAffectedFiles().stream().map(it -> it.toString()).collect(Collectors.toList()); - return list.stream().collect(Collectors.joining("\n")); - } - - - //获取git地址 - @SneakyThrows - public static String getGitAddress(Project project) { - return null; - } - - //获取最后一条commit记录 - @SneakyThrows - public static List getLastCommit(Project project) { - return null; - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/ImportUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/ImportUtils.java deleted file mode 100644 index a2cb51720..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/util/ImportUtils.java +++ /dev/null @@ -1,52 +0,0 @@ -package run.mone.m78.ip.util; - -import com.google.common.base.Splitter; -import com.intellij.codeInsight.actions.OptimizeImportsAction; -import com.intellij.codeInspection.unusedImport.UnusedImportInspection; -import com.intellij.openapi.actionSystem.ActionPlaces; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; -import com.intellij.psi.*; -import com.intellij.psi.impl.source.PsiJavaFileImpl; -import com.intellij.psi.util.PsiTreeUtil; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -/** - * @author goodjava@qq.com - * @date 2023/6/22 21:41 - */ -@Slf4j -public abstract class ImportUtils { - - public static void removeInvalidImports(Project project, Editor editor) { - } - - public static void optimizeImports(Project project, Editor editor) { - - } - - - public static void addImport(Project project, Editor editor, List importStrList) { - - } - - public static PsiClass createPsiClass(PsiElementFactory factory, String className) { - return null; - } - - - public static String junitVersion(PsiClass psiClass) { - return ""; - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/PromptUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/PromptUtils.java deleted file mode 100644 index e25a9fa58..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/util/PromptUtils.java +++ /dev/null @@ -1,257 +0,0 @@ -package run.mone.m78.ip.util; - -import com.google.common.collect.Maps; -import com.google.gson.Gson; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiClass; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.dialog.DialogResult; -import run.mone.m78.ip.service.CodeService; -import run.mone.m78.ip.bo.CreateClassMeta; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.common.ConfigUtils; -import run.mone.m78.ip.dialog.ChromeDialog; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.ObjectUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.net.URLEncoder; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * @author goodjava@qq.com - * @date 2023/5/29 10:09 - */ -@Slf4j -public class PromptUtils { - - - private static final Gson gson = new Gson(); - - - public static Map getParamsFromAiProxy(String promptName, String metaStr) { - return getParamsFromAiProxy(promptName, metaStr, false); - } - - public static Map getParamsFromAiProxy(String promptName, String metaStr, boolean useSelect) { - return Maps.newHashMap(); - } - - - /** - * 创建类(class enum) - * - * @param project - * @param modelName - * @param promptName - */ - public static void createClass(Project project, final String modelName, String promptName) { - - } - - private static String getModelName(String modelName, Map values) { - if (StringUtils.isEmpty(modelName)) { - modelName = values.getOrDefault("module", "").toString(); - } - return modelName; - } - - @Nullable - private static String[] getParams(CreateClassMeta createClassMeta, Editor editor) { - String[] params = null; - if (ObjectUtils.notEqual(null, createClassMeta) && createClassMeta.isUseSelect()) { - params = new String[]{EditorUtils.getSelectContent(editor)}; - } - return params; - } - - - public static void createClass2(Project project, String promptName, String showDialog, Map param) { - String isShowDialog = StringUtils.isEmpty(showDialog) ? "true" : showDialog; - PromptInfo promptInfo = Prompt.getPromptInfo(promptName); - Map v = getParamsFromAiProxy(promptName, promptInfo.getMeta()); - if ("true".equals(isShowDialog)) { - String url = buildDialogUrl(project, v, promptInfo); - ChromeDialog chromeDialog = new ChromeDialog(url, project); - chromeDialog.show(); - return; - } - - String packageStr = param.get("package").toString(); - String className = param.get("class").toString(); - String modelName = param.get("modelName").toString(); - - CodeService.createEmptyClass(project, modelName, packageStr, className); - - PsiClass psiClass = CodeService.getPsiClass2(project); - TextRange textRange = psiClass.getTextRange(); - CodeService.deleteTextRange(project, psiClass.getTextRange()); - Editor codeEditor = CodeService.getEditor(project); - codeEditor.getCaretModel().moveToOffset(textRange.getStartOffset()); - - Map pm = param.entrySet().stream().collect(Collectors.toMap(en -> en.getKey(), en -> en.getValue().toString())); - CodeService.generateCodeWithAi3(project, promptName, new String[]{}, pm, (p, code) -> CodeService.writeCode2(p, codeEditor, code)); - - } - - - /** - * $$->隐藏 - * $@$->选择框 - * - * @param project - * @param param - * @param promptInfo - * @return - */ - private static String buildDialogUrl(Project project, Map param, PromptInfo promptInfo) { - if (!param.containsKey("model")) { - param.put("$@$model", ProjectUtils.listAllModules(project)); - } - if (!param.containsKey("package")) { - param.put("package", ""); - } - if (param.containsKey("class")) { - param.put("class", ""); - } - param.put("$$showDialog", "false"); - param.put("$$prompt", promptInfo.getPromptName()); - param.put("$$desc", promptInfo.getDesc()); - return ConfigUtils.getConfig().getChatServer() + "/code-form" + "?param=" + URLEncoder.encode(gson.toJson(param)); - } - - /** - * 给方法添加注释 - * - * @param req - */ - public static void addComment(GenerateCodeReq req) { - - } - - - /** - * 修改class - * - * @param project - * @param promptName - */ - public static void modifyClass(Project project, String promptName) { - PsiClass psiClass = CodeService.getPsiClass2(project); - String codeStr = psiClass.getText(); - CodeService.deletePsiClass(project, psiClass); - Editor codeEditor = CodeService.getEditor(project); - CodeService.generateCodeWithAi2(project, promptName, new String[]{codeStr}, (p, code) -> CodeService.writeCode2(p, codeEditor, code)); - } - - - /** - * 创建一个文件 - * - * @param req - */ - public static void createFile(String promptName, String fileName, GenerateCodeReq req) { - - } - - /** - * @param req - */ - public static void updateClass(GenerateCodeReq req) { - PsiClass psiClass = CodeService.getPsiClass(req.getProject()); - String classCode = psiClass.getText(); - TextRange textRange = psiClass.getTextRange(); - CodeService.deleteTextRange(req.getProject(), textRange); - Editor editor = CodeService.getEditor(req.getProject()); - CodeService.generateCodeWithAi2(req.getProject(), req.getPromptName(), new String[]{classCode}, (p, code) -> CodeService.writeCode2(p, editor, code)); - } - - /** - * 更新方法 - * - * @param req - */ - public static void updateMethod(GenerateCodeReq req) { - - } - - /** - * 给一个方法添加逐行注释,或者代码 - * - * @param promptName - * @param req - */ - public static void lineByLineCommentOrCode(String promptName, GenerateCodeReq req) { - - } - - private static String filterAnnoCode(String codeStr, PromptInfo promptInfo) { - return codeStr; - } - - private static void addImportList(Project project, Map map) { - - } - - public static List getImportList(PromptInfo promptInfo) { - return null; - } - - /** - * @param req - * @param map - * @return - */ - @NotNull - private static String getCode(GenerateCodeReq req, Map map) { - return ""; - } - - @NotNull - private static String getScope(GenerateCodeReq req, Map map) { - return ""; - } - - - private static Pair getPackageAndClass(DialogResult result) { - return null; - } - - private static DialogResult showDialog(Project project, Module module, String data) { - return null; - } - - /** - * 生成接口 - * - * @param req - */ - public static void generateInterface(GenerateCodeReq req) { - - - } - - /** - * 用来生成测试方法 - */ - public static void select(GenerateCodeReq req, Project project, Module module, PromptInfo promptInfo) { - - } - - public static void checkPomVersion(GenerateCodeReq req) { - } - - public static void generateAnnoForBootStrap(String promptName, Project project) { - - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/TerminalUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/TerminalUtils.java deleted file mode 100644 index 88701e92f..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/util/TerminalUtils.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.util; - -import com.intellij.execution.ExecutionException; -import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.execution.process.OSProcessHandler; -import com.intellij.execution.process.ProcessAdapter; -import com.intellij.execution.process.ProcessEvent; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.ProjectManager; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.wm.ToolWindow; -import com.intellij.openapi.wm.ToolWindowAnchor; -import com.intellij.openapi.wm.ToolWindowManager; -import com.intellij.openapi.wm.ex.ToolWindowManagerEx; -import com.intellij.terminal.JBTerminalPanel; -import com.jediterm.terminal.TerminalOutputStream; -import lombok.SneakyThrows; - -import javax.swing.*; -import java.util.concurrent.TimeUnit; - -/** - * @Author goodjava@qq.com - * @Date 2021/11/7 11:21 - */ -public class TerminalUtils { - - @SneakyThrows - public static void show(Project project) { - ToolWindowManager toolWindowManager = ToolWindowManager.getInstance(project); - ToolWindow terminal = toolWindowManager.getToolWindow("Terminal"); - if (terminal != null) { - terminal.show(null); - if (!terminal.isActive()) { - TimeUnit.SECONDS.sleep(1); - } - } - } - - - public static void send(Project project, String message) { - - } - - public static ToolWindow getTerminalToolWindow(Project project) { - return null; - } - - - public static void runCommandOnTerminal(Project project, String command) { - - - } - - - private static Object getPannel(Object root) { - if (root instanceof JBTerminalPanel) { - return root; - } - if (root instanceof JPanel) { - return getPannel(((JPanel) root).getComponent(0)); - } - if (root instanceof JLayeredPane) { - return getPannel(((JLayeredPane) root).getComponent(0)); - } - return null; - } - - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/util/TestUtils.java b/athena-all/src/main/java/run/mone/m78/ip/util/TestUtils.java deleted file mode 100644 index 17010eea2..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/util/TestUtils.java +++ /dev/null @@ -1,52 +0,0 @@ -package run.mone.m78.ip.util; - -import com.google.common.collect.Lists; - -import java.util.List; - -/** - * @author goodjava@qq.com - * @date 2023/8/11 09:46 - */ -public class TestUtils { - - - public static List junitImportList = Lists.newArrayList("import org.junit.Test", "import org.junit.Assert"); - - public static List jupiterImportList = Lists.newArrayList("import org.junit.jupiter.api.Test", "import static org.junit.jupiter.api.Assertions.assertEquals", "import static org.junit.jupiter.api.Assertions.assertNotNull"); - - - public static boolean isJupiter() { - if (isClassPresent("org.junit.Test")) { - return false; - } else if (isClassPresent("org.junit.jupiter.api.Test")) { - return true; - } else { - return false; - } - } - - public static List getImportList(String version) { - if (version.equals("unknow")) { - return Lists.newArrayList(); - } - if (version.equals("junit")) { - return junitImportList; - } - if (version.equals("jupiter")) { - return junitImportList; - } - return Lists.newArrayList(); - } - - - private static boolean isClassPresent(String className) { - try { - Class.forName(className); - return true; - } catch (ClassNotFoundException e) { - return false; - } - } - -} diff --git a/athena-all/src/main/java/run/mone/m78/ip/window/UltramanWindowFactory.java b/athena-all/src/main/java/run/mone/m78/ip/window/UltramanWindowFactory.java deleted file mode 100644 index cc72bfb50..000000000 --- a/athena-all/src/main/java/run/mone/m78/ip/window/UltramanWindowFactory.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2020 Xiaomi - * - * 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 run.mone.m78.ip.window; - -import com.intellij.openapi.project.Project; -import com.intellij.openapi.wm.ToolWindow; -import com.intellij.openapi.wm.ToolWindowFactory; -import com.intellij.ui.content.Content; -import com.intellij.ui.content.ContentFactory; -import run.mone.m78.ip.ui.UltramanTreeUi; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; - -/** - * @Author goodjava@qq.com - * @Date 2021/11/8 20:55 - */ -public class UltramanWindowFactory implements ToolWindowFactory { - - @Override - public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) { - ContentFactory contentFactory = ContentFactory.getInstance(); - JPanel pannel = new UltramanTreeUi(project).jpanel(); - Content content = contentFactory.createContent(pannel, "", false); - toolWindow.getContentManager().addContent(content); - - } -} diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/CommonUtils.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/CommonUtils.java deleted file mode 100644 index 08671b6db..000000000 --- a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/CommonUtils.java +++ /dev/null @@ -1,19 +0,0 @@ -package run.mone.mone.ultraman.grpc; - -import java.util.List; -import java.util.stream.Collectors; - -/** - * @author goodjava@qq.com - * @date 2023/8/1 15:10 - */ -public class CommonUtils { - - - //ai:给你两个List,帮我计算交集 - public List getIntersection(List list1, List list2) { - return list1.stream().filter(list2::contains).collect(Collectors.toList()); - } - - -} diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/Service.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/Service.java deleted file mode 100644 index c9e9c2279..000000000 --- a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/Service.java +++ /dev/null @@ -1,87 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: service.proto - -package run.mone.mone.ultraman.grpc; - -public final class Service { - private Service() {} - public static void registerAllExtensions( - com.google.protobuf.ExtensionRegistryLite registry) { - } - - public static void registerAllExtensions( - com.google.protobuf.ExtensionRegistry registry) { - registerAllExtensions( - (com.google.protobuf.ExtensionRegistryLite) registry); - } - static final com.google.protobuf.Descriptors.Descriptor - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor; - static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_fieldAccessorTable; - static final com.google.protobuf.Descriptors.Descriptor - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_descriptor; - static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_fieldAccessorTable; - static final com.google.protobuf.Descriptors.Descriptor - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor; - static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_fieldAccessorTable; - static final com.google.protobuf.Descriptors.Descriptor - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_descriptor; - static final - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_fieldAccessorTable; - - public static com.google.protobuf.Descriptors.FileDescriptor - getDescriptor() { - return descriptor; - } - private static com.google.protobuf.Descriptors.FileDescriptor - descriptor; - static { - String[] descriptorData = { - - }; - com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = - new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { - public com.google.protobuf.ExtensionRegistry assignDescriptors( - com.google.protobuf.Descriptors.FileDescriptor root) { - descriptor = root; - return null; - } - }; - com.google.protobuf.Descriptors.FileDescriptor - .internalBuildGeneratedFileFrom(descriptorData, - new com.google.protobuf.Descriptors.FileDescriptor[] { - }, assigner); - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor = - getDescriptor().getMessageTypes().get(0); - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor, - new String[] { "Id", "Cmd", "Params", "ParamMap", }); - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_descriptor = - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor.getNestedTypes().get(0); - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_descriptor, - new String[] { "Key", "Value", }); - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor = - getDescriptor().getMessageTypes().get(1); - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor, - new String[] { "Id", "Data", "Code", "Cmd", "ResMap", }); - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_descriptor = - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor.getNestedTypes().get(0); - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_fieldAccessorTable = new - com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( - internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_descriptor, - new String[] { "Key", "Value", }); - } - - // @@protoc_insertion_point(outer_class_scope) -} diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequest.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequest.java deleted file mode 100644 index 83bff749e..000000000 --- a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequest.java +++ /dev/null @@ -1,1073 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: service.proto - -package run.mone.mone.ultraman.grpc; - -/** - * Protobuf type {@code com.xiaomi.mone.ultraman.grpc.UltramanRequest} - */ -public final class UltramanRequest extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:com.xiaomi.mone.ultraman.grpc.UltramanRequest) - UltramanRequestOrBuilder { -private static final long serialVersionUID = 0L; - // Use UltramanRequest.newBuilder() to construct. - private UltramanRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private UltramanRequest() { - id_ = ""; - cmd_ = ""; - params_ = ""; - } - - @Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private UltramanRequest( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new NullPointerException(); - } - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - String s = input.readStringRequireUtf8(); - - id_ = s; - break; - } - case 18: { - String s = input.readStringRequireUtf8(); - - cmd_ = s; - break; - } - case 26: { - String s = input.readStringRequireUtf8(); - - params_ = s; - break; - } - case 34: { - if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) { - paramMap_ = com.google.protobuf.MapField.newMapField( - ParamMapDefaultEntryHolder.defaultEntry); - mutable_bitField0_ |= 0x00000008; - } - com.google.protobuf.MapEntry - paramMap__ = input.readMessage( - ParamMapDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); - paramMap_.getMutableMap().put( - paramMap__.getKey(), paramMap__.getValue()); - break; - } - default: { - if (!parseUnknownFieldProto3( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor; - } - - @SuppressWarnings({"rawtypes"}) - @Override - protected com.google.protobuf.MapField internalGetMapField( - int number) { - switch (number) { - case 4: - return internalGetParamMap(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - @Override - protected FieldAccessorTable - internalGetFieldAccessorTable() { - return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_fieldAccessorTable - .ensureFieldAccessorsInitialized( - UltramanRequest.class, Builder.class); - } - - private int bitField0_; - public static final int ID_FIELD_NUMBER = 1; - private volatile Object id_; - /** - * string id = 1; - */ - public String getId() { - Object ref = id_; - if (ref instanceof String) { - return (String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - id_ = s; - return s; - } - } - /** - * string id = 1; - */ - public com.google.protobuf.ByteString - getIdBytes() { - Object ref = id_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int CMD_FIELD_NUMBER = 2; - private volatile Object cmd_; - /** - * string cmd = 2; - */ - public String getCmd() { - Object ref = cmd_; - if (ref instanceof String) { - return (String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - cmd_ = s; - return s; - } - } - /** - * string cmd = 2; - */ - public com.google.protobuf.ByteString - getCmdBytes() { - Object ref = cmd_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - cmd_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int PARAMS_FIELD_NUMBER = 3; - private volatile Object params_; - /** - * string params = 3; - */ - public String getParams() { - Object ref = params_; - if (ref instanceof String) { - return (String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - params_ = s; - return s; - } - } - /** - * string params = 3; - */ - public com.google.protobuf.ByteString - getParamsBytes() { - Object ref = params_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - params_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int PARAMMAP_FIELD_NUMBER = 4; - private static final class ParamMapDefaultEntryHolder { - static final com.google.protobuf.MapEntry< - String, String> defaultEntry = - com.google.protobuf.MapEntry - .newDefaultInstance( - Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_ParamMapEntry_descriptor, - com.google.protobuf.WireFormat.FieldType.STRING, - "", - com.google.protobuf.WireFormat.FieldType.STRING, - ""); - } - private com.google.protobuf.MapField< - String, String> paramMap_; - private com.google.protobuf.MapField - internalGetParamMap() { - if (paramMap_ == null) { - return com.google.protobuf.MapField.emptyMapField( - ParamMapDefaultEntryHolder.defaultEntry); - } - return paramMap_; - } - - public int getParamMapCount() { - return internalGetParamMap().getMap().size(); - } - /** - * map<string, string> paramMap = 4; - */ - - public boolean containsParamMap( - String key) { - if (key == null) { throw new NullPointerException(); } - return internalGetParamMap().getMap().containsKey(key); - } - /** - * Use {@link #getParamMapMap()} instead. - */ - @Deprecated - public java.util.Map getParamMap() { - return getParamMapMap(); - } - /** - * map<string, string> paramMap = 4; - */ - - public java.util.Map getParamMapMap() { - return internalGetParamMap().getMap(); - } - /** - * map<string, string> paramMap = 4; - */ - - public String getParamMapOrDefault( - String key, - String defaultValue) { - if (key == null) { throw new NullPointerException(); } - java.util.Map map = - internalGetParamMap().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; - } - /** - * map<string, string> paramMap = 4; - */ - - public String getParamMapOrThrow( - String key) { - if (key == null) { throw new NullPointerException(); } - java.util.Map map = - internalGetParamMap().getMap(); - if (!map.containsKey(key)) { - throw new IllegalArgumentException(); - } - return map.get(key); - } - - private byte memoizedIsInitialized = -1; - @Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - @Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (!getIdBytes().isEmpty()) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, id_); - } - if (!getCmdBytes().isEmpty()) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 2, cmd_); - } - if (!getParamsBytes().isEmpty()) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 3, params_); - } - com.google.protobuf.GeneratedMessageV3 - .serializeStringMapTo( - output, - internalGetParamMap(), - ParamMapDefaultEntryHolder.defaultEntry, - 4); - unknownFields.writeTo(output); - } - - @Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (!getIdBytes().isEmpty()) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, id_); - } - if (!getCmdBytes().isEmpty()) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, cmd_); - } - if (!getParamsBytes().isEmpty()) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, params_); - } - for (java.util.Map.Entry entry - : internalGetParamMap().getMap().entrySet()) { - com.google.protobuf.MapEntry - paramMap__ = ParamMapDefaultEntryHolder.defaultEntry.newBuilderForType() - .setKey(entry.getKey()) - .setValue(entry.getValue()) - .build(); - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(4, paramMap__); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @Override - public boolean equals(final Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof UltramanRequest)) { - return super.equals(obj); - } - UltramanRequest other = (UltramanRequest) obj; - - boolean result = true; - result = result && getId() - .equals(other.getId()); - result = result && getCmd() - .equals(other.getCmd()); - result = result && getParams() - .equals(other.getParams()); - result = result && internalGetParamMap().equals( - other.internalGetParamMap()); - result = result && unknownFields.equals(other.unknownFields); - return result; - } - - @Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - hash = (37 * hash) + ID_FIELD_NUMBER; - hash = (53 * hash) + getId().hashCode(); - hash = (37 * hash) + CMD_FIELD_NUMBER; - hash = (53 * hash) + getCmd().hashCode(); - hash = (37 * hash) + PARAMS_FIELD_NUMBER; - hash = (53 * hash) + getParams().hashCode(); - if (!internalGetParamMap().getMap().isEmpty()) { - hash = (37 * hash) + PARAMMAP_FIELD_NUMBER; - hash = (53 * hash) + internalGetParamMap().hashCode(); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static UltramanRequest parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static UltramanRequest parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static UltramanRequest parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static UltramanRequest parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static UltramanRequest parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static UltramanRequest parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static UltramanRequest parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static UltramanRequest parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static UltramanRequest parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static UltramanRequest parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static UltramanRequest parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static UltramanRequest parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(UltramanRequest prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @Override - protected Builder newBuilderForType( - BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code com.xiaomi.mone.ultraman.grpc.UltramanRequest} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:com.xiaomi.mone.ultraman.grpc.UltramanRequest) - UltramanRequestOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor; - } - - @SuppressWarnings({"rawtypes"}) - protected com.google.protobuf.MapField internalGetMapField( - int number) { - switch (number) { - case 4: - return internalGetParamMap(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - @SuppressWarnings({"rawtypes"}) - protected com.google.protobuf.MapField internalGetMutableMapField( - int number) { - switch (number) { - case 4: - return internalGetMutableParamMap(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - @Override - protected FieldAccessorTable - internalGetFieldAccessorTable() { - return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_fieldAccessorTable - .ensureFieldAccessorsInitialized( - UltramanRequest.class, Builder.class); - } - - // Construct using com.xiaomi.mone.ultraman.grpc.UltramanRequest.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - } - } - @Override - public Builder clear() { - super.clear(); - id_ = ""; - - cmd_ = ""; - - params_ = ""; - - internalGetMutableParamMap().clear(); - return this; - } - - @Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanRequest_descriptor; - } - - @Override - public UltramanRequest getDefaultInstanceForType() { - return UltramanRequest.getDefaultInstance(); - } - - @Override - public UltramanRequest build() { - UltramanRequest result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @Override - public UltramanRequest buildPartial() { - UltramanRequest result = new UltramanRequest(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - result.id_ = id_; - result.cmd_ = cmd_; - result.params_ = params_; - result.paramMap_ = internalGetParamMap(); - result.paramMap_.makeImmutable(); - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - @Override - public Builder clone() { - return (Builder) super.clone(); - } - @Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - Object value) { - return (Builder) super.setField(field, value); - } - @Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return (Builder) super.clearField(field); - } - @Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return (Builder) super.clearOneof(oneof); - } - @Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, Object value) { - return (Builder) super.setRepeatedField(field, index, value); - } - @Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - Object value) { - return (Builder) super.addRepeatedField(field, value); - } - @Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof UltramanRequest) { - return mergeFrom((UltramanRequest)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(UltramanRequest other) { - if (other == UltramanRequest.getDefaultInstance()) return this; - if (!other.getId().isEmpty()) { - id_ = other.id_; - onChanged(); - } - if (!other.getCmd().isEmpty()) { - cmd_ = other.cmd_; - onChanged(); - } - if (!other.getParams().isEmpty()) { - params_ = other.params_; - onChanged(); - } - internalGetMutableParamMap().mergeFrom( - other.internalGetParamMap()); - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @Override - public final boolean isInitialized() { - return true; - } - - @Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - UltramanRequest parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (UltramanRequest) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - private Object id_ = ""; - /** - * string id = 1; - */ - public String getId() { - Object ref = id_; - if (!(ref instanceof String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - id_ = s; - return s; - } else { - return (String) ref; - } - } - /** - * string id = 1; - */ - public com.google.protobuf.ByteString - getIdBytes() { - Object ref = id_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * string id = 1; - */ - public Builder setId( - String value) { - if (value == null) { - throw new NullPointerException(); - } - - id_ = value; - onChanged(); - return this; - } - /** - * string id = 1; - */ - public Builder clearId() { - - id_ = getDefaultInstance().getId(); - onChanged(); - return this; - } - /** - * string id = 1; - */ - public Builder setIdBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - - id_ = value; - onChanged(); - return this; - } - - private Object cmd_ = ""; - /** - * string cmd = 2; - */ - public String getCmd() { - Object ref = cmd_; - if (!(ref instanceof String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - cmd_ = s; - return s; - } else { - return (String) ref; - } - } - /** - * string cmd = 2; - */ - public com.google.protobuf.ByteString - getCmdBytes() { - Object ref = cmd_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - cmd_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * string cmd = 2; - */ - public Builder setCmd( - String value) { - if (value == null) { - throw new NullPointerException(); - } - - cmd_ = value; - onChanged(); - return this; - } - /** - * string cmd = 2; - */ - public Builder clearCmd() { - - cmd_ = getDefaultInstance().getCmd(); - onChanged(); - return this; - } - /** - * string cmd = 2; - */ - public Builder setCmdBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - - cmd_ = value; - onChanged(); - return this; - } - - private Object params_ = ""; - /** - * string params = 3; - */ - public String getParams() { - Object ref = params_; - if (!(ref instanceof String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - params_ = s; - return s; - } else { - return (String) ref; - } - } - /** - * string params = 3; - */ - public com.google.protobuf.ByteString - getParamsBytes() { - Object ref = params_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - params_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * string params = 3; - */ - public Builder setParams( - String value) { - if (value == null) { - throw new NullPointerException(); - } - - params_ = value; - onChanged(); - return this; - } - /** - * string params = 3; - */ - public Builder clearParams() { - - params_ = getDefaultInstance().getParams(); - onChanged(); - return this; - } - /** - * string params = 3; - */ - public Builder setParamsBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - - params_ = value; - onChanged(); - return this; - } - - private com.google.protobuf.MapField< - String, String> paramMap_; - private com.google.protobuf.MapField - internalGetParamMap() { - if (paramMap_ == null) { - return com.google.protobuf.MapField.emptyMapField( - ParamMapDefaultEntryHolder.defaultEntry); - } - return paramMap_; - } - private com.google.protobuf.MapField - internalGetMutableParamMap() { - onChanged();; - if (paramMap_ == null) { - paramMap_ = com.google.protobuf.MapField.newMapField( - ParamMapDefaultEntryHolder.defaultEntry); - } - if (!paramMap_.isMutable()) { - paramMap_ = paramMap_.copy(); - } - return paramMap_; - } - - public int getParamMapCount() { - return internalGetParamMap().getMap().size(); - } - /** - * map<string, string> paramMap = 4; - */ - - public boolean containsParamMap( - String key) { - if (key == null) { throw new NullPointerException(); } - return internalGetParamMap().getMap().containsKey(key); - } - /** - * Use {@link #getParamMapMap()} instead. - */ - @Deprecated - public java.util.Map getParamMap() { - return getParamMapMap(); - } - /** - * map<string, string> paramMap = 4; - */ - - public java.util.Map getParamMapMap() { - return internalGetParamMap().getMap(); - } - /** - * map<string, string> paramMap = 4; - */ - - public String getParamMapOrDefault( - String key, - String defaultValue) { - if (key == null) { throw new NullPointerException(); } - java.util.Map map = - internalGetParamMap().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; - } - /** - * map<string, string> paramMap = 4; - */ - - public String getParamMapOrThrow( - String key) { - if (key == null) { throw new NullPointerException(); } - java.util.Map map = - internalGetParamMap().getMap(); - if (!map.containsKey(key)) { - throw new IllegalArgumentException(); - } - return map.get(key); - } - - public Builder clearParamMap() { - internalGetMutableParamMap().getMutableMap() - .clear(); - return this; - } - /** - * map<string, string> paramMap = 4; - */ - - public Builder removeParamMap( - String key) { - if (key == null) { throw new NullPointerException(); } - internalGetMutableParamMap().getMutableMap() - .remove(key); - return this; - } - /** - * Use alternate mutation accessors instead. - */ - @Deprecated - public java.util.Map - getMutableParamMap() { - return internalGetMutableParamMap().getMutableMap(); - } - /** - * map<string, string> paramMap = 4; - */ - public Builder putParamMap( - String key, - String value) { - if (key == null) { throw new NullPointerException(); } - if (value == null) { throw new NullPointerException(); } - internalGetMutableParamMap().getMutableMap() - .put(key, value); - return this; - } - /** - * map<string, string> paramMap = 4; - */ - - public Builder putAllParamMap( - java.util.Map values) { - internalGetMutableParamMap().getMutableMap() - .putAll(values); - return this; - } - @Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFieldsProto3(unknownFields); - } - - @Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:com.xiaomi.mone.ultraman.grpc.UltramanRequest) - } - - // @@protoc_insertion_point(class_scope:com.xiaomi.mone.ultraman.grpc.UltramanRequest) - private static final UltramanRequest DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new UltramanRequest(); - } - - public static UltramanRequest getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @Override - public UltramanRequest parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new UltramanRequest(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @Override - public UltramanRequest getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - -} - diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequestOrBuilder.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequestOrBuilder.java deleted file mode 100644 index 521ac7441..000000000 --- a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanRequestOrBuilder.java +++ /dev/null @@ -1,73 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: service.proto - -package run.mone.mone.ultraman.grpc; - -public interface UltramanRequestOrBuilder extends - // @@protoc_insertion_point(interface_extends:com.xiaomi.mone.ultraman.grpc.UltramanRequest) - com.google.protobuf.MessageOrBuilder { - - /** - * string id = 1; - */ - String getId(); - /** - * string id = 1; - */ - com.google.protobuf.ByteString - getIdBytes(); - - /** - * string cmd = 2; - */ - String getCmd(); - /** - * string cmd = 2; - */ - com.google.protobuf.ByteString - getCmdBytes(); - - /** - * string params = 3; - */ - String getParams(); - /** - * string params = 3; - */ - com.google.protobuf.ByteString - getParamsBytes(); - - /** - * map<string, string> paramMap = 4; - */ - int getParamMapCount(); - /** - * map<string, string> paramMap = 4; - */ - boolean containsParamMap( - String key); - /** - * Use {@link #getParamMapMap()} instead. - */ - @Deprecated - java.util.Map - getParamMap(); - /** - * map<string, string> paramMap = 4; - */ - java.util.Map - getParamMapMap(); - /** - * map<string, string> paramMap = 4; - */ - - String getParamMapOrDefault( - String key, - String defaultValue); - /** - * map<string, string> paramMap = 4; - */ - - String getParamMapOrThrow( - String key); -} diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponse.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponse.java deleted file mode 100644 index 003facbf1..000000000 --- a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponse.java +++ /dev/null @@ -1,1131 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: service.proto - -package run.mone.mone.ultraman.grpc; - -/** - * Protobuf type {@code com.xiaomi.mone.ultraman.grpc.UltramanResponse} - */ -public final class UltramanResponse extends - com.google.protobuf.GeneratedMessageV3 implements - // @@protoc_insertion_point(message_implements:com.xiaomi.mone.ultraman.grpc.UltramanResponse) - UltramanResponseOrBuilder { -private static final long serialVersionUID = 0L; - // Use UltramanResponse.newBuilder() to construct. - private UltramanResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { - super(builder); - } - private UltramanResponse() { - id_ = ""; - data_ = ""; - code_ = 0; - cmd_ = ""; - } - - @Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private UltramanResponse( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - this(); - if (extensionRegistry == null) { - throw new NullPointerException(); - } - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - case 10: { - String s = input.readStringRequireUtf8(); - - id_ = s; - break; - } - case 18: { - String s = input.readStringRequireUtf8(); - - data_ = s; - break; - } - case 24: { - - code_ = input.readInt32(); - break; - } - case 34: { - String s = input.readStringRequireUtf8(); - - cmd_ = s; - break; - } - case 42: { - if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { - resMap_ = com.google.protobuf.MapField.newMapField( - ResMapDefaultEntryHolder.defaultEntry); - mutable_bitField0_ |= 0x00000010; - } - com.google.protobuf.MapEntry - resMap__ = input.readMessage( - ResMapDefaultEntryHolder.defaultEntry.getParserForType(), extensionRegistry); - resMap_.getMutableMap().put( - resMap__.getKey(), resMap__.getValue()); - break; - } - default: { - if (!parseUnknownFieldProto3( - input, unknownFields, extensionRegistry, tag)) { - done = true; - } - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor; - } - - @SuppressWarnings({"rawtypes"}) - @Override - protected com.google.protobuf.MapField internalGetMapField( - int number) { - switch (number) { - case 5: - return internalGetResMap(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - @Override - protected FieldAccessorTable - internalGetFieldAccessorTable() { - return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_fieldAccessorTable - .ensureFieldAccessorsInitialized( - UltramanResponse.class, Builder.class); - } - - private int bitField0_; - public static final int ID_FIELD_NUMBER = 1; - private volatile Object id_; - /** - * string id = 1; - */ - public String getId() { - Object ref = id_; - if (ref instanceof String) { - return (String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - id_ = s; - return s; - } - } - /** - * string id = 1; - */ - public com.google.protobuf.ByteString - getIdBytes() { - Object ref = id_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int DATA_FIELD_NUMBER = 2; - private volatile Object data_; - /** - * string data = 2; - */ - public String getData() { - Object ref = data_; - if (ref instanceof String) { - return (String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - data_ = s; - return s; - } - } - /** - * string data = 2; - */ - public com.google.protobuf.ByteString - getDataBytes() { - Object ref = data_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - data_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int CODE_FIELD_NUMBER = 3; - private int code_; - /** - * int32 code = 3; - */ - public int getCode() { - return code_; - } - - public static final int CMD_FIELD_NUMBER = 4; - private volatile Object cmd_; - /** - * string cmd = 4; - */ - public String getCmd() { - Object ref = cmd_; - if (ref instanceof String) { - return (String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - cmd_ = s; - return s; - } - } - /** - * string cmd = 4; - */ - public com.google.protobuf.ByteString - getCmdBytes() { - Object ref = cmd_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - cmd_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - public static final int RESMAP_FIELD_NUMBER = 5; - private static final class ResMapDefaultEntryHolder { - static final com.google.protobuf.MapEntry< - String, String> defaultEntry = - com.google.protobuf.MapEntry - .newDefaultInstance( - Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_ResMapEntry_descriptor, - com.google.protobuf.WireFormat.FieldType.STRING, - "", - com.google.protobuf.WireFormat.FieldType.STRING, - ""); - } - private com.google.protobuf.MapField< - String, String> resMap_; - private com.google.protobuf.MapField - internalGetResMap() { - if (resMap_ == null) { - return com.google.protobuf.MapField.emptyMapField( - ResMapDefaultEntryHolder.defaultEntry); - } - return resMap_; - } - - public int getResMapCount() { - return internalGetResMap().getMap().size(); - } - /** - * map<string, string> resMap = 5; - */ - - public boolean containsResMap( - String key) { - if (key == null) { throw new NullPointerException(); } - return internalGetResMap().getMap().containsKey(key); - } - /** - * Use {@link #getResMapMap()} instead. - */ - @Deprecated - public java.util.Map getResMap() { - return getResMapMap(); - } - /** - * map<string, string> resMap = 5; - */ - - public java.util.Map getResMapMap() { - return internalGetResMap().getMap(); - } - /** - * map<string, string> resMap = 5; - */ - - public String getResMapOrDefault( - String key, - String defaultValue) { - if (key == null) { throw new NullPointerException(); } - java.util.Map map = - internalGetResMap().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; - } - /** - * map<string, string> resMap = 5; - */ - - public String getResMapOrThrow( - String key) { - if (key == null) { throw new NullPointerException(); } - java.util.Map map = - internalGetResMap().getMap(); - if (!map.containsKey(key)) { - throw new IllegalArgumentException(); - } - return map.get(key); - } - - private byte memoizedIsInitialized = -1; - @Override - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized == 1) return true; - if (isInitialized == 0) return false; - - memoizedIsInitialized = 1; - return true; - } - - @Override - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - if (!getIdBytes().isEmpty()) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 1, id_); - } - if (!getDataBytes().isEmpty()) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 2, data_); - } - if (code_ != 0) { - output.writeInt32(3, code_); - } - if (!getCmdBytes().isEmpty()) { - com.google.protobuf.GeneratedMessageV3.writeString(output, 4, cmd_); - } - com.google.protobuf.GeneratedMessageV3 - .serializeStringMapTo( - output, - internalGetResMap(), - ResMapDefaultEntryHolder.defaultEntry, - 5); - unknownFields.writeTo(output); - } - - @Override - public int getSerializedSize() { - int size = memoizedSize; - if (size != -1) return size; - - size = 0; - if (!getIdBytes().isEmpty()) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, id_); - } - if (!getDataBytes().isEmpty()) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, data_); - } - if (code_ != 0) { - size += com.google.protobuf.CodedOutputStream - .computeInt32Size(3, code_); - } - if (!getCmdBytes().isEmpty()) { - size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, cmd_); - } - for (java.util.Map.Entry entry - : internalGetResMap().getMap().entrySet()) { - com.google.protobuf.MapEntry - resMap__ = ResMapDefaultEntryHolder.defaultEntry.newBuilderForType() - .setKey(entry.getKey()) - .setValue(entry.getValue()) - .build(); - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(5, resMap__); - } - size += unknownFields.getSerializedSize(); - memoizedSize = size; - return size; - } - - @Override - public boolean equals(final Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof UltramanResponse)) { - return super.equals(obj); - } - UltramanResponse other = (UltramanResponse) obj; - - boolean result = true; - result = result && getId() - .equals(other.getId()); - result = result && getData() - .equals(other.getData()); - result = result && (getCode() - == other.getCode()); - result = result && getCmd() - .equals(other.getCmd()); - result = result && internalGetResMap().equals( - other.internalGetResMap()); - result = result && unknownFields.equals(other.unknownFields); - return result; - } - - @Override - public int hashCode() { - if (memoizedHashCode != 0) { - return memoizedHashCode; - } - int hash = 41; - hash = (19 * hash) + getDescriptor().hashCode(); - hash = (37 * hash) + ID_FIELD_NUMBER; - hash = (53 * hash) + getId().hashCode(); - hash = (37 * hash) + DATA_FIELD_NUMBER; - hash = (53 * hash) + getData().hashCode(); - hash = (37 * hash) + CODE_FIELD_NUMBER; - hash = (53 * hash) + getCode(); - hash = (37 * hash) + CMD_FIELD_NUMBER; - hash = (53 * hash) + getCmd().hashCode(); - if (!internalGetResMap().getMap().isEmpty()) { - hash = (37 * hash) + RESMAP_FIELD_NUMBER; - hash = (53 * hash) + internalGetResMap().hashCode(); - } - hash = (29 * hash) + unknownFields.hashCode(); - memoizedHashCode = hash; - return hash; - } - - public static UltramanResponse parseFrom( - java.nio.ByteBuffer data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static UltramanResponse parseFrom( - java.nio.ByteBuffer data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static UltramanResponse parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static UltramanResponse parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static UltramanResponse parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static UltramanResponse parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static UltramanResponse parseFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static UltramanResponse parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - public static UltramanResponse parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input); - } - public static UltramanResponse parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseDelimitedWithIOException(PARSER, input, extensionRegistry); - } - public static UltramanResponse parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input); - } - public static UltramanResponse parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return com.google.protobuf.GeneratedMessageV3 - .parseWithIOException(PARSER, input, extensionRegistry); - } - - @Override - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder() { - return DEFAULT_INSTANCE.toBuilder(); - } - public static Builder newBuilder(UltramanResponse prototype) { - return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); - } - @Override - public Builder toBuilder() { - return this == DEFAULT_INSTANCE - ? new Builder() : new Builder().mergeFrom(this); - } - - @Override - protected Builder newBuilderForType( - BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code com.xiaomi.mone.ultraman.grpc.UltramanResponse} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessageV3.Builder implements - // @@protoc_insertion_point(builder_implements:com.xiaomi.mone.ultraman.grpc.UltramanResponse) - UltramanResponseOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor; - } - - @SuppressWarnings({"rawtypes"}) - protected com.google.protobuf.MapField internalGetMapField( - int number) { - switch (number) { - case 5: - return internalGetResMap(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - @SuppressWarnings({"rawtypes"}) - protected com.google.protobuf.MapField internalGetMutableMapField( - int number) { - switch (number) { - case 5: - return internalGetMutableResMap(); - default: - throw new RuntimeException( - "Invalid map field number: " + number); - } - } - @Override - protected FieldAccessorTable - internalGetFieldAccessorTable() { - return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_fieldAccessorTable - .ensureFieldAccessorsInitialized( - UltramanResponse.class, Builder.class); - } - - // Construct using com.xiaomi.mone.ultraman.grpc.UltramanResponse.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessageV3 - .alwaysUseFieldBuilders) { - } - } - @Override - public Builder clear() { - super.clear(); - id_ = ""; - - data_ = ""; - - code_ = 0; - - cmd_ = ""; - - internalGetMutableResMap().clear(); - return this; - } - - @Override - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return Service.internal_static_com_xiaomi_mone_ultraman_grpc_UltramanResponse_descriptor; - } - - @Override - public UltramanResponse getDefaultInstanceForType() { - return UltramanResponse.getDefaultInstance(); - } - - @Override - public UltramanResponse build() { - UltramanResponse result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - @Override - public UltramanResponse buildPartial() { - UltramanResponse result = new UltramanResponse(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - result.id_ = id_; - result.data_ = data_; - result.code_ = code_; - result.cmd_ = cmd_; - result.resMap_ = internalGetResMap(); - result.resMap_.makeImmutable(); - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - @Override - public Builder clone() { - return (Builder) super.clone(); - } - @Override - public Builder setField( - com.google.protobuf.Descriptors.FieldDescriptor field, - Object value) { - return (Builder) super.setField(field, value); - } - @Override - public Builder clearField( - com.google.protobuf.Descriptors.FieldDescriptor field) { - return (Builder) super.clearField(field); - } - @Override - public Builder clearOneof( - com.google.protobuf.Descriptors.OneofDescriptor oneof) { - return (Builder) super.clearOneof(oneof); - } - @Override - public Builder setRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - int index, Object value) { - return (Builder) super.setRepeatedField(field, index, value); - } - @Override - public Builder addRepeatedField( - com.google.protobuf.Descriptors.FieldDescriptor field, - Object value) { - return (Builder) super.addRepeatedField(field, value); - } - @Override - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof UltramanResponse) { - return mergeFrom((UltramanResponse)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(UltramanResponse other) { - if (other == UltramanResponse.getDefaultInstance()) return this; - if (!other.getId().isEmpty()) { - id_ = other.id_; - onChanged(); - } - if (!other.getData().isEmpty()) { - data_ = other.data_; - onChanged(); - } - if (other.getCode() != 0) { - setCode(other.getCode()); - } - if (!other.getCmd().isEmpty()) { - cmd_ = other.cmd_; - onChanged(); - } - internalGetMutableResMap().mergeFrom( - other.internalGetResMap()); - this.mergeUnknownFields(other.unknownFields); - onChanged(); - return this; - } - - @Override - public final boolean isInitialized() { - return true; - } - - @Override - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - UltramanResponse parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (UltramanResponse) e.getUnfinishedMessage(); - throw e.unwrapIOException(); - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - private Object id_ = ""; - /** - * string id = 1; - */ - public String getId() { - Object ref = id_; - if (!(ref instanceof String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - id_ = s; - return s; - } else { - return (String) ref; - } - } - /** - * string id = 1; - */ - public com.google.protobuf.ByteString - getIdBytes() { - Object ref = id_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - id_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * string id = 1; - */ - public Builder setId( - String value) { - if (value == null) { - throw new NullPointerException(); - } - - id_ = value; - onChanged(); - return this; - } - /** - * string id = 1; - */ - public Builder clearId() { - - id_ = getDefaultInstance().getId(); - onChanged(); - return this; - } - /** - * string id = 1; - */ - public Builder setIdBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - - id_ = value; - onChanged(); - return this; - } - - private Object data_ = ""; - /** - * string data = 2; - */ - public String getData() { - Object ref = data_; - if (!(ref instanceof String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - data_ = s; - return s; - } else { - return (String) ref; - } - } - /** - * string data = 2; - */ - public com.google.protobuf.ByteString - getDataBytes() { - Object ref = data_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - data_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * string data = 2; - */ - public Builder setData( - String value) { - if (value == null) { - throw new NullPointerException(); - } - - data_ = value; - onChanged(); - return this; - } - /** - * string data = 2; - */ - public Builder clearData() { - - data_ = getDefaultInstance().getData(); - onChanged(); - return this; - } - /** - * string data = 2; - */ - public Builder setDataBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - - data_ = value; - onChanged(); - return this; - } - - private int code_ ; - /** - * int32 code = 3; - */ - public int getCode() { - return code_; - } - /** - * int32 code = 3; - */ - public Builder setCode(int value) { - - code_ = value; - onChanged(); - return this; - } - /** - * int32 code = 3; - */ - public Builder clearCode() { - - code_ = 0; - onChanged(); - return this; - } - - private Object cmd_ = ""; - /** - * string cmd = 4; - */ - public String getCmd() { - Object ref = cmd_; - if (!(ref instanceof String)) { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - String s = bs.toStringUtf8(); - cmd_ = s; - return s; - } else { - return (String) ref; - } - } - /** - * string cmd = 4; - */ - public com.google.protobuf.ByteString - getCmdBytes() { - Object ref = cmd_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (String) ref); - cmd_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * string cmd = 4; - */ - public Builder setCmd( - String value) { - if (value == null) { - throw new NullPointerException(); - } - - cmd_ = value; - onChanged(); - return this; - } - /** - * string cmd = 4; - */ - public Builder clearCmd() { - - cmd_ = getDefaultInstance().getCmd(); - onChanged(); - return this; - } - /** - * string cmd = 4; - */ - public Builder setCmdBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - checkByteStringIsUtf8(value); - - cmd_ = value; - onChanged(); - return this; - } - - private com.google.protobuf.MapField< - String, String> resMap_; - private com.google.protobuf.MapField - internalGetResMap() { - if (resMap_ == null) { - return com.google.protobuf.MapField.emptyMapField( - ResMapDefaultEntryHolder.defaultEntry); - } - return resMap_; - } - private com.google.protobuf.MapField - internalGetMutableResMap() { - onChanged();; - if (resMap_ == null) { - resMap_ = com.google.protobuf.MapField.newMapField( - ResMapDefaultEntryHolder.defaultEntry); - } - if (!resMap_.isMutable()) { - resMap_ = resMap_.copy(); - } - return resMap_; - } - - public int getResMapCount() { - return internalGetResMap().getMap().size(); - } - /** - * map<string, string> resMap = 5; - */ - - public boolean containsResMap( - String key) { - if (key == null) { throw new NullPointerException(); } - return internalGetResMap().getMap().containsKey(key); - } - /** - * Use {@link #getResMapMap()} instead. - */ - @Deprecated - public java.util.Map getResMap() { - return getResMapMap(); - } - /** - * map<string, string> resMap = 5; - */ - - public java.util.Map getResMapMap() { - return internalGetResMap().getMap(); - } - /** - * map<string, string> resMap = 5; - */ - - public String getResMapOrDefault( - String key, - String defaultValue) { - if (key == null) { throw new NullPointerException(); } - java.util.Map map = - internalGetResMap().getMap(); - return map.containsKey(key) ? map.get(key) : defaultValue; - } - /** - * map<string, string> resMap = 5; - */ - - public String getResMapOrThrow( - String key) { - if (key == null) { throw new NullPointerException(); } - java.util.Map map = - internalGetResMap().getMap(); - if (!map.containsKey(key)) { - throw new IllegalArgumentException(); - } - return map.get(key); - } - - public Builder clearResMap() { - internalGetMutableResMap().getMutableMap() - .clear(); - return this; - } - /** - * map<string, string> resMap = 5; - */ - - public Builder removeResMap( - String key) { - if (key == null) { throw new NullPointerException(); } - internalGetMutableResMap().getMutableMap() - .remove(key); - return this; - } - /** - * Use alternate mutation accessors instead. - */ - @Deprecated - public java.util.Map - getMutableResMap() { - return internalGetMutableResMap().getMutableMap(); - } - /** - * map<string, string> resMap = 5; - */ - public Builder putResMap( - String key, - String value) { - if (key == null) { throw new NullPointerException(); } - if (value == null) { throw new NullPointerException(); } - internalGetMutableResMap().getMutableMap() - .put(key, value); - return this; - } - /** - * map<string, string> resMap = 5; - */ - - public Builder putAllResMap( - java.util.Map values) { - internalGetMutableResMap().getMutableMap() - .putAll(values); - return this; - } - @Override - public final Builder setUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.setUnknownFieldsProto3(unknownFields); - } - - @Override - public final Builder mergeUnknownFields( - final com.google.protobuf.UnknownFieldSet unknownFields) { - return super.mergeUnknownFields(unknownFields); - } - - - // @@protoc_insertion_point(builder_scope:com.xiaomi.mone.ultraman.grpc.UltramanResponse) - } - - // @@protoc_insertion_point(class_scope:com.xiaomi.mone.ultraman.grpc.UltramanResponse) - private static final UltramanResponse DEFAULT_INSTANCE; - static { - DEFAULT_INSTANCE = new UltramanResponse(); - } - - public static UltramanResponse getDefaultInstance() { - return DEFAULT_INSTANCE; - } - - private static final com.google.protobuf.Parser - PARSER = new com.google.protobuf.AbstractParser() { - @Override - public UltramanResponse parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new UltramanResponse(input, extensionRegistry); - } - }; - - public static com.google.protobuf.Parser parser() { - return PARSER; - } - - @Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - @Override - public UltramanResponse getDefaultInstanceForType() { - return DEFAULT_INSTANCE; - } - -} - diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponseOrBuilder.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponseOrBuilder.java deleted file mode 100644 index 0c098e04c..000000000 --- a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanResponseOrBuilder.java +++ /dev/null @@ -1,78 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: service.proto - -package run.mone.mone.ultraman.grpc; - -public interface UltramanResponseOrBuilder extends - // @@protoc_insertion_point(interface_extends:com.xiaomi.mone.ultraman.grpc.UltramanResponse) - com.google.protobuf.MessageOrBuilder { - - /** - * string id = 1; - */ - String getId(); - /** - * string id = 1; - */ - com.google.protobuf.ByteString - getIdBytes(); - - /** - * string data = 2; - */ - String getData(); - /** - * string data = 2; - */ - com.google.protobuf.ByteString - getDataBytes(); - - /** - * int32 code = 3; - */ - int getCode(); - - /** - * string cmd = 4; - */ - String getCmd(); - /** - * string cmd = 4; - */ - com.google.protobuf.ByteString - getCmdBytes(); - - /** - * map<string, string> resMap = 5; - */ - int getResMapCount(); - /** - * map<string, string> resMap = 5; - */ - boolean containsResMap( - String key); - /** - * Use {@link #getResMapMap()} instead. - */ - @Deprecated - java.util.Map - getResMap(); - /** - * map<string, string> resMap = 5; - */ - java.util.Map - getResMapMap(); - /** - * map<string, string> resMap = 5; - */ - - String getResMapOrDefault( - String key, - String defaultValue); - /** - * map<string, string> resMap = 5; - */ - - String getResMapOrThrow( - String key); -} diff --git a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanServiceGrpc.java b/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanServiceGrpc.java deleted file mode 100644 index c46af6dc9..000000000 --- a/athena-all/src/main/java/run/mone/mone/ultraman/grpc/UltramanServiceGrpc.java +++ /dev/null @@ -1,401 +0,0 @@ -package run.mone.mone.ultraman.grpc; - -import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; - -/** - */ -@javax.annotation.Generated( - value = "by gRPC proto compiler (version 1.34.1)", - comments = "Source: service.proto") -public final class UltramanServiceGrpc { - - private UltramanServiceGrpc() {} - - public static final String SERVICE_NAME = "com.xiaomi.mone.ultraman.grpc.UltramanService"; - - // Static method descriptors that strictly reflect the proto. - private static volatile io.grpc.MethodDescriptor getHelloMethod; - - @io.grpc.stub.annotations.RpcMethod( - fullMethodName = SERVICE_NAME + '/' + "hello", - requestType = UltramanRequest.class, - responseType = UltramanResponse.class, - methodType = io.grpc.MethodDescriptor.MethodType.UNARY) - public static io.grpc.MethodDescriptor getHelloMethod() { - io.grpc.MethodDescriptor getHelloMethod; - if ((getHelloMethod = UltramanServiceGrpc.getHelloMethod) == null) { - synchronized (UltramanServiceGrpc.class) { - if ((getHelloMethod = UltramanServiceGrpc.getHelloMethod) == null) { - UltramanServiceGrpc.getHelloMethod = getHelloMethod = - io.grpc.MethodDescriptor.newBuilder() - .setType(io.grpc.MethodDescriptor.MethodType.UNARY) - .setFullMethodName(generateFullMethodName(SERVICE_NAME, "hello")) - .setSampledToLocalTracing(true) - .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( - UltramanRequest.getDefaultInstance())) - .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( - UltramanResponse.getDefaultInstance())) - .setSchemaDescriptor(new UltramanServiceMethodDescriptorSupplier("hello")) - .build(); - } - } - } - return getHelloMethod; - } - - private static volatile io.grpc.MethodDescriptor getStreamMethod; - - @io.grpc.stub.annotations.RpcMethod( - fullMethodName = SERVICE_NAME + '/' + "stream", - requestType = UltramanRequest.class, - responseType = UltramanResponse.class, - methodType = io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING) - public static io.grpc.MethodDescriptor getStreamMethod() { - io.grpc.MethodDescriptor getStreamMethod; - if ((getStreamMethod = UltramanServiceGrpc.getStreamMethod) == null) { - synchronized (UltramanServiceGrpc.class) { - if ((getStreamMethod = UltramanServiceGrpc.getStreamMethod) == null) { - UltramanServiceGrpc.getStreamMethod = getStreamMethod = - io.grpc.MethodDescriptor.newBuilder() - .setType(io.grpc.MethodDescriptor.MethodType.BIDI_STREAMING) - .setFullMethodName(generateFullMethodName(SERVICE_NAME, "stream")) - .setSampledToLocalTracing(true) - .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( - UltramanRequest.getDefaultInstance())) - .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( - UltramanResponse.getDefaultInstance())) - .setSchemaDescriptor(new UltramanServiceMethodDescriptorSupplier("stream")) - .build(); - } - } - } - return getStreamMethod; - } - - private static volatile io.grpc.MethodDescriptor getCallMethod; - - @io.grpc.stub.annotations.RpcMethod( - fullMethodName = SERVICE_NAME + '/' + "call", - requestType = UltramanRequest.class, - responseType = UltramanResponse.class, - methodType = io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) - public static io.grpc.MethodDescriptor getCallMethod() { - io.grpc.MethodDescriptor getCallMethod; - if ((getCallMethod = UltramanServiceGrpc.getCallMethod) == null) { - synchronized (UltramanServiceGrpc.class) { - if ((getCallMethod = UltramanServiceGrpc.getCallMethod) == null) { - UltramanServiceGrpc.getCallMethod = getCallMethod = - io.grpc.MethodDescriptor.newBuilder() - .setType(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) - .setFullMethodName(generateFullMethodName(SERVICE_NAME, "call")) - .setSampledToLocalTracing(true) - .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( - UltramanRequest.getDefaultInstance())) - .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( - UltramanResponse.getDefaultInstance())) - .setSchemaDescriptor(new UltramanServiceMethodDescriptorSupplier("call")) - .build(); - } - } - } - return getCallMethod; - } - - /** - * Creates a new async stub that supports all call types for the service - */ - public static UltramanServiceStub newStub(io.grpc.Channel channel) { - io.grpc.stub.AbstractStub.StubFactory factory = - new io.grpc.stub.AbstractStub.StubFactory() { - @Override - public UltramanServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { - return new UltramanServiceStub(channel, callOptions); - } - }; - return UltramanServiceStub.newStub(factory, channel); - } - - /** - * Creates a new blocking-style stub that supports unary and streaming output calls on the service - */ - public static UltramanServiceBlockingStub newBlockingStub( - io.grpc.Channel channel) { - io.grpc.stub.AbstractStub.StubFactory factory = - new io.grpc.stub.AbstractStub.StubFactory() { - @Override - public UltramanServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { - return new UltramanServiceBlockingStub(channel, callOptions); - } - }; - return UltramanServiceBlockingStub.newStub(factory, channel); - } - - /** - * Creates a new ListenableFuture-style stub that supports unary calls on the service - */ - public static UltramanServiceFutureStub newFutureStub( - io.grpc.Channel channel) { - io.grpc.stub.AbstractStub.StubFactory factory = - new io.grpc.stub.AbstractStub.StubFactory() { - @Override - public UltramanServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { - return new UltramanServiceFutureStub(channel, callOptions); - } - }; - return UltramanServiceFutureStub.newStub(factory, channel); - } - - /** - */ - public static abstract class UltramanServiceImplBase implements io.grpc.BindableService { - - /** - */ - public void hello(UltramanRequest request, - io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getHelloMethod(), responseObserver); - } - - /** - */ - public io.grpc.stub.StreamObserver stream( - io.grpc.stub.StreamObserver responseObserver) { - return asyncUnimplementedStreamingCall(getStreamMethod(), responseObserver); - } - - /** - */ - public io.grpc.stub.StreamObserver call( - io.grpc.stub.StreamObserver responseObserver) { - return asyncUnimplementedStreamingCall(getCallMethod(), responseObserver); - } - - @Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getHelloMethod(), - asyncUnaryCall( - new MethodHandlers< - UltramanRequest, - UltramanResponse>( - this, METHODID_HELLO))) - .addMethod( - getStreamMethod(), - asyncBidiStreamingCall( - new MethodHandlers< - UltramanRequest, - UltramanResponse>( - this, METHODID_STREAM))) - .addMethod( - getCallMethod(), - asyncClientStreamingCall( - new MethodHandlers< - UltramanRequest, - UltramanResponse>( - this, METHODID_CALL))) - .build(); - } - } - - /** - */ - public static final class UltramanServiceStub extends io.grpc.stub.AbstractAsyncStub { - private UltramanServiceStub( - io.grpc.Channel channel, io.grpc.CallOptions callOptions) { - super(channel, callOptions); - } - - @Override - protected UltramanServiceStub build( - io.grpc.Channel channel, io.grpc.CallOptions callOptions) { - return new UltramanServiceStub(channel, callOptions); - } - - /** - */ - public void hello(UltramanRequest request, - io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( - getChannel().newCall(getHelloMethod(), getCallOptions()), request, responseObserver); - } - - /** - */ - public io.grpc.stub.StreamObserver stream( - io.grpc.stub.StreamObserver responseObserver) { - return asyncBidiStreamingCall( - getChannel().newCall(getStreamMethod(), getCallOptions()), responseObserver); - } - - /** - */ - public io.grpc.stub.StreamObserver call( - io.grpc.stub.StreamObserver responseObserver) { - return asyncClientStreamingCall( - getChannel().newCall(getCallMethod(), getCallOptions()), responseObserver); - } - } - - /** - */ - public static final class UltramanServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { - private UltramanServiceBlockingStub( - io.grpc.Channel channel, io.grpc.CallOptions callOptions) { - super(channel, callOptions); - } - - @Override - protected UltramanServiceBlockingStub build( - io.grpc.Channel channel, io.grpc.CallOptions callOptions) { - return new UltramanServiceBlockingStub(channel, callOptions); - } - - /** - */ - public UltramanResponse hello(UltramanRequest request) { - return blockingUnaryCall( - getChannel(), getHelloMethod(), getCallOptions(), request); - } - } - - /** - */ - public static final class UltramanServiceFutureStub extends io.grpc.stub.AbstractFutureStub { - private UltramanServiceFutureStub( - io.grpc.Channel channel, io.grpc.CallOptions callOptions) { - super(channel, callOptions); - } - - @Override - protected UltramanServiceFutureStub build( - io.grpc.Channel channel, io.grpc.CallOptions callOptions) { - return new UltramanServiceFutureStub(channel, callOptions); - } - - /** - */ - public com.google.common.util.concurrent.ListenableFuture hello( - UltramanRequest request) { - return futureUnaryCall( - getChannel().newCall(getHelloMethod(), getCallOptions()), request); - } - } - - private static final int METHODID_HELLO = 0; - private static final int METHODID_STREAM = 1; - private static final int METHODID_CALL = 2; - - private static final class MethodHandlers implements - io.grpc.stub.ServerCalls.UnaryMethod, - io.grpc.stub.ServerCalls.ServerStreamingMethod, - io.grpc.stub.ServerCalls.ClientStreamingMethod, - io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final UltramanServiceImplBase serviceImpl; - private final int methodId; - - MethodHandlers(UltramanServiceImplBase serviceImpl, int methodId) { - this.serviceImpl = serviceImpl; - this.methodId = methodId; - } - - @Override - @SuppressWarnings("unchecked") - public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { - switch (methodId) { - case METHODID_HELLO: - serviceImpl.hello((UltramanRequest) request, - (io.grpc.stub.StreamObserver) responseObserver); - break; - default: - throw new AssertionError(); - } - } - - @Override - @SuppressWarnings("unchecked") - public io.grpc.stub.StreamObserver invoke( - io.grpc.stub.StreamObserver responseObserver) { - switch (methodId) { - case METHODID_STREAM: - return (io.grpc.stub.StreamObserver) serviceImpl.stream( - (io.grpc.stub.StreamObserver) responseObserver); - case METHODID_CALL: - return (io.grpc.stub.StreamObserver) serviceImpl.call( - (io.grpc.stub.StreamObserver) responseObserver); - default: - throw new AssertionError(); - } - } - } - - private static abstract class UltramanServiceBaseDescriptorSupplier - implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier { - UltramanServiceBaseDescriptorSupplier() {} - - @Override - public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { - return Service.getDescriptor(); - } - - @Override - public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() { - return getFileDescriptor().findServiceByName("UltramanService"); - } - } - - private static final class UltramanServiceFileDescriptorSupplier - extends UltramanServiceBaseDescriptorSupplier { - UltramanServiceFileDescriptorSupplier() {} - } - - private static final class UltramanServiceMethodDescriptorSupplier - extends UltramanServiceBaseDescriptorSupplier - implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { - private final String methodName; - - UltramanServiceMethodDescriptorSupplier(String methodName) { - this.methodName = methodName; - } - - @Override - public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() { - return getServiceDescriptor().findMethodByName(methodName); - } - } - - private static volatile io.grpc.ServiceDescriptor serviceDescriptor; - - public static io.grpc.ServiceDescriptor getServiceDescriptor() { - io.grpc.ServiceDescriptor result = serviceDescriptor; - if (result == null) { - synchronized (UltramanServiceGrpc.class) { - result = serviceDescriptor; - if (result == null) { - serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) - .setSchemaDescriptor(new UltramanServiceFileDescriptorSupplier()) - .addMethod(getHelloMethod()) - .addMethod(getStreamMethod()) - .addMethod(getCallMethod()) - .build(); - } - } - } - return result; - } -} diff --git a/athena-all/src/main/java/run/mone/ultraman/AthenaContext.java b/athena-all/src/main/java/run/mone/ultraman/AthenaContext.java index 57250c706..f2debfa19 100644 --- a/athena-all/src/main/java/run/mone/ultraman/AthenaContext.java +++ b/athena-all/src/main/java/run/mone/ultraman/AthenaContext.java @@ -1,8 +1,8 @@ package run.mone.ultraman; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.bo.ModelRes; -import run.mone.m78.ip.listener.UltrmanTreeKeyAdapter; +import com.xiaomi.youpin.tesla.ip.bo.ModelRes; +import com.xiaomi.youpin.tesla.ip.listener.UltrmanTreeKeyAdapter; import lombok.Data; import org.apache.commons.lang3.StringUtils; import run.mone.ultraman.bo.ClientData; @@ -29,10 +29,16 @@ public class AthenaContext { private String zAddr; + private String userName; + private List models; private Map modelMap; + private String localAddress; + + private String localPort; + //models 直接 转换为 modelMap,key是 ModelRes中的 value(class) public void convertModelsToModelMap() { @@ -60,14 +66,23 @@ public ClientData getClientData(String projectName) { } /** - * chatgpt的模型 + * 聊天模型 */ private String gptModel = ""; + /** + * 非聊天模型 + */ + private String noChatModel = ""; + public int getMaxTokenNum() { return getModel(gptModel).getMaxToken(); } + public int getNoChatMaxTokenNum() { + return getModel(noChatModel).getMaxToken(); + } + public ModelRes gptModel() { if (StringUtils.isEmpty(this.gptModel)) { return null; @@ -75,6 +90,13 @@ public ModelRes gptModel() { return getModel(this.gptModel); } + public ModelRes noChatModel() { + if (StringUtils.isEmpty(this.noChatModel)) { + return null; + } + return getModel(this.noChatModel); + } + private List modelList = new ArrayList<>(); private String token; diff --git a/athena-all/src/main/java/run/mone/ultraman/AthenaInspection.java b/athena-all/src/main/java/run/mone/ultraman/AthenaInspection.java index 81c3551fb..a2056be94 100644 --- a/athena-all/src/main/java/run/mone/ultraman/AthenaInspection.java +++ b/athena-all/src/main/java/run/mone/ultraman/AthenaInspection.java @@ -1,24 +1,30 @@ package run.mone.ultraman; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; import com.intellij.codeInspection.*; import com.intellij.codeInspection.util.IntentionFamilyName; import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.common.PromptType; -import run.mone.m78.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.util.EditorUtils; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; +import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; /** * @author goodjava@qq.com - * 对方法进行重命名 - * @date 2022/5/2 09:19 */ public class AthenaInspection extends AbstractBaseJavaLocalInspectionTool { @@ -27,33 +33,73 @@ public class AthenaInspection extends AbstractBaseJavaLocalInspectionTool { public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { return new JavaElementVisitor() { + @Override + public void visitParameter(@NotNull PsiParameter parameter) { + if (ResourceUtils.checkDisableCodeCompletionStatus()) return; + + // 获取参数名 + String paramName = parameter.getName(); + // 获取参数类型 + PsiElement parent = parameter.getParent(); + if (parent instanceof PsiParameterList) { + PsiElement grandparent = parent.getParent(); + if (ResourceUtils.checkDisableCodeCompletionStatus()) return; + + if (grandparent instanceof PsiMethod) { + holder.registerProblem(parameter, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { + @Override + public @IntentionFamilyName @NotNull String getFamilyName() { + return Const.PLUGIN_NAME + "(参数命名)"; + } + + + //参数重命名 + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + HashMap param = Maps.newHashMap(); + param.put("paramName", paramName); + invokePrompt(project, "rename_param_name", param, ImmutableMap.of("parameter", parameter)); + } + }); + + } + } + + + } + //analyse_class @Override public void visitClass(PsiClass aClass) { + if (ResourceUtils.checkDisableCodeCompletionStatus()) return; - holder.registerProblem(aClass, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { + List> list = Prompt.getPromptInfoByTag("class_inspection").stream() + .filter(it -> it.isCollected() || Prompt.containsTag(it.getTags(), "system")) + .map(it -> Pair.of(it.getDesc(), it.getPromptName())) + .collect(Collectors.toList()); + + list.forEach(it -> holder.registerProblem(aClass, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { @Override public @IntentionFamilyName @NotNull String getFamilyName() { - return "Athena(类分析)"; + return it.getKey(); } - //类分析 @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - String promptName = "analyse_class"; - invokePrompt(project,promptName); + String promptName = it.getValue(); + invokePrompt(project, promptName, Maps.newHashMap()); } - }); + })); + } - // rename_method(方法重命名) comment_2(方法添加注释) suggest_sidecar(方法review+建议) + // rename_method(方法重命名) comment_2(方法添加注释) suggest_sidecar(方法review+建议) test_code(单元测试) @Override public void visitMethod(PsiMethod method) { - List> list = Prompt.getPromptInfoByTag("method_inspection").stream() - .filter(it -> it.isCollected() || Prompt.containsTag(it.getTags(), "system")) - .map(it -> Pair.of(it.getDesc(), it.getPromptName())) - .collect(Collectors.toList()); + if (ResourceUtils.checkDisableCodeCompletionStatus()) return; + + List> list = getPromptMethodMenu(); list.forEach(it -> holder.registerProblem(method, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { @Override public @IntentionFamilyName @NotNull String getFamilyName() { @@ -63,7 +109,12 @@ public void visitMethod(PsiMethod method) { @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { String promptName = it.getValue(); - invokePrompt(project,promptName); + invokePrompt(project, promptName, Maps.newHashMap()); + } + + @Override + public boolean startInWriteAction() { + return false; } })); @@ -73,23 +124,69 @@ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descri @Override //访问注释 public void visitComment(@NotNull PsiComment comment) { - //直接生成代码 + if (ResourceUtils.checkDisableCodeCompletionStatus()) return; + //单行注释 直接生成代码 if (comment.getText().startsWith("//")) { - final String content = comment.getText().substring(2); - holder.registerProblem(comment, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { - @Override - //获取修复的家族名称 - public @IntentionFamilyName @NotNull String getFamilyName() { - return "Athena(生成方法)"; - } - - @Override - //应用修复 - public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - //根据注释生成代码 - PromptService.generateMethod(project, content); - } - }); + //注释范围在 (method, class] + if (EditorUtils.isCommentInsideClass(comment) + && EditorUtils.isNotClassHeaderComment(comment) + && isNotMethodComment(comment)) { + final String content = comment.getText().substring(2); + holder.registerProblem(comment, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { + @Override + //获取修复的家族名称 + public @IntentionFamilyName @NotNull String getFamilyName() { + return Const.PLUGIN_NAME + "(生成代码)"; + } + + @Override + //应用修复 + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + PromptInfo promptInfo = Prompt.getPromptInfo(Const.GENERATE_CODE); + if (isBotUsageConfigured(promptInfo)) { + //调用bot生成代码 + invokePrompt(project, promptInfo.getPromptName(), Maps.newHashMap()); + } else { + //根据注释生成代码 + PromptService.generateMethod(project, content); + } + } + }); + } + } + + // 处理多行注释 + if (comment.getText().startsWith("/*")) { + if (EditorUtils.isCommentInsideClass(comment) + && EditorUtils.isNotClassHeaderComment(comment) + && isNotMethodComment(comment)) { + final String content = comment.getText().trim(); + holder.registerProblem(comment, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { + @Override + public @IntentionFamilyName @NotNull String getFamilyName() { + return Const.PLUGIN_NAME + "(生成代码)"; + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + // 移动光标到注释末尾 + PsiElement element = descriptor.getPsiElement(); + if (element instanceof PsiComment) { + PsiComment comment = (PsiComment) element; + EditorUtils.moveCaretToCommentEnd(project, comment); + } + + PromptInfo promptInfo = Prompt.getPromptInfo(Const.GENERATE_CODE); + if (isBotUsageConfigured(promptInfo)) { + Map parms = Maps.newHashMap(); + parms.put(Const.GENERATE_CODE_COMMENT, content); + invokePrompt(project, promptInfo.getPromptName(), parms); + } else { + PromptService.generateMethod(project, content); + } + } + }); + } } } @@ -99,33 +196,62 @@ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descri */ @Override public void visitField(PsiField field) { + if (ResourceUtils.checkDisableCodeCompletionStatus()) return; holder.registerProblem(field, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { @Override public @IntentionFamilyName @NotNull String getFamilyName() { - return "Athena(字段重命名)"; + return Const.PLUGIN_NAME + "(字段重命名)"; } @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { String promptName = "rename_field"; - invokePrompt(project, promptName); + invokePrompt(project, promptName, Maps.newHashMap()); } }); } }; } + //查询方法级菜单列表 + private List> getPromptMethodMenu() { + List> list = Prompt.getPromptInfoByTag("method_inspection").stream() + .filter(it -> it.isCollected() || Prompt.containsTag(it.getTags(), "popup")) + .sorted(Comparator.comparingInt(it -> Integer.parseInt(it.getLabels().getOrDefault("order", "1")))) + .map(it -> Pair.of(it.getDesc(), it.getPromptName())) + .collect(Collectors.toList()); + return list; + } + + private static boolean isNotMethodComment(@NotNull PsiComment comment) { + return !(comment.getParent() instanceof PsiMethod); + } + - public static void invokePrompt(Project project, String promptName) { + public static void invokePrompt(Project project, String promptName, Map param) { + invokePrompt(project, promptName, param, Maps.newHashMap()); + } + + public static void invokePrompt(Project project, String promptName, Map param, Map objMap) { PromptInfo promptInfo = Prompt.getPromptInfo(promptName); PromptType promptType = Prompt.getPromptType(promptInfo); + //直接使用bot + if (isBotUsageConfigured(promptInfo)) { + promptType = PromptType.executeBot; + } PromptService.dynamicInvoke(GenerateCodeReq.builder() .project(project) .promptType(promptType) .promptName(promptName) .promptInfo(promptInfo) + .param(param) + .objMap(objMap) .build()); } + //是否是调用bot来执行 + public static boolean isBotUsageConfigured(PromptInfo promptInfo) { + return ResourceUtils.has(Const.USE_BOT) && promptInfo.has(Const.BOT_ID) && !(promptInfo.getLabels().get(Const.BOT_ID).equals("0")); + } } diff --git a/athena-all/src/main/java/run/mone/ultraman/AthenaSuggestionInspection.java b/athena-all/src/main/java/run/mone/ultraman/AthenaSuggestionInspection.java index eba5aa615..4f4a3cb47 100644 --- a/athena-all/src/main/java/run/mone/ultraman/AthenaSuggestionInspection.java +++ b/athena-all/src/main/java/run/mone/ultraman/AthenaSuggestionInspection.java @@ -6,12 +6,13 @@ import com.intellij.psi.JavaElementVisitor; import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiMethod; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.Message; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.common.PromptType; -import run.mone.m78.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.Message; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; import org.jetbrains.annotations.NotNull; /** @@ -20,6 +21,7 @@ */ public class AthenaSuggestionInspection extends AbstractBaseJavaLocalInspectionTool { + //代码修改建议 private static final String promptName = "hi2"; @NotNull @@ -29,10 +31,10 @@ public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean is @Override public void visitMethod(PsiMethod method) { - if (true) { - return; - } super.visitMethod(method); + + if (ResourceUtils.checkDisableCodeCompletionStatus()) return; + holder.registerProblem(method, "", ProblemHighlightType.INFORMATION, new LocalQuickFix() { @Override @@ -44,12 +46,12 @@ public void visitMethod(PsiMethod method) { public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { PromptInfo promptInfo = Prompt.getPromptInfo(promptName); PromptType promptType = Prompt.getPromptType(promptInfo); - PromptService.inlayHint(GenerateCodeReq.builder() - .promptName(promptName) - .promptInfo(promptInfo) - .promptType(promptType) - .project(project) - .projectName(project.getName()).build()); + PromptService.dynamicInvoke(GenerateCodeReq.builder() + .promptName(promptName) + .promptInfo(promptInfo) + .promptType(promptType) + .project(project) + .projectName(project.getName()).build()); } }); } diff --git a/athena-all/src/main/java/run/mone/ultraman/DemoService.java b/athena-all/src/main/java/run/mone/ultraman/DemoService.java index f1dd49a07..de7cd99ed 100644 --- a/athena-all/src/main/java/run/mone/ultraman/DemoService.java +++ b/athena-all/src/main/java/run/mone/ultraman/DemoService.java @@ -1,6 +1,15 @@ package run.mone.ultraman; +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + /** * @author goodjava@qq.com * @date 2023/6/7 18:20 @@ -8,5 +17,27 @@ public class DemoService { + //ai:截取当前桌面,保存到指定文件(filePath参数),如果截取成功,则返回"ok" + public String captureDesktop(String filePath) { + try { + Robot robot = new Robot(); + Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); + BufferedImage image = robot.createScreenCapture(screenRect); + File file = new File(filePath); + ImageIO.write(image, "png", file); + return "ok"; + } catch (Exception e) { + e.printStackTrace(); + return "error"; + } + } + + //ai:根据提供的的文件地址,读取文件内容,用String返回 + public String readFile(String filePath) throws IOException { + Path path = Paths.get(filePath); + return Files.readString(path); + } + + } diff --git a/athena-all/src/main/java/run/mone/ultraman/HttpServerHandler.java b/athena-all/src/main/java/run/mone/ultraman/HttpServerHandler.java index 6db1c2640..9987088bf 100644 --- a/athena-all/src/main/java/run/mone/ultraman/HttpServerHandler.java +++ b/athena-all/src/main/java/run/mone/ultraman/HttpServerHandler.java @@ -1,7 +1,26 @@ package run.mone.ultraman; -import com.google.gson.Gson; -import com.google.gson.JsonObject; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.gson.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.RobotContext; +import com.xiaomi.youpin.tesla.ip.bo.RobotReq; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.JavaClassUtils; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.RobotService; +import com.xiaomi.youpin.tesla.ip.util.*; +import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; @@ -9,17 +28,400 @@ import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.util.CharsetUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.mutable.MutableObject; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; +import run.mone.openai.OpenaiCall; +import run.mone.ultraman.bo.AiReq; +import run.mone.ultraman.bo.AthenaClassInfo; +import run.mone.ultraman.common.ActionEventUtils; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.common.PythonExecutor; +import run.mone.ultraman.common.SafeRun; +import run.mone.ultraman.http.HttpClient; import run.mone.ultraman.http.HttpResponseUtils; +import run.mone.ultraman.http.Param; +import run.mone.ultraman.http.handler.ReadCodeHandler; +import run.mone.ultraman.http.handler.WriteCodeHandler; +import run.mone.ultraman.service.AgentService; +import run.mone.ultraman.service.AthenaCodeService; +import run.mone.ultraman.state.PromptAndFunctionProcessor; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Clip; +import java.io.ByteArrayInputStream; +import java.net.URI; +import java.util.Base64; +import java.util.List; +import java.util.Optional; + +@Slf4j public class HttpServerHandler extends SimpleChannelInboundHandler { private Gson gson = new Gson(); @Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception { + String uri = req.uri(); + + // 使用java.net.URI解析URI字符串 + URI parsedUri = new URI(uri); + + // 获取路径部分 + String path = parsedUri.getPath(); + + if (uri.startsWith("/favicon.ico")) { + ctx.writeAndFlush(HttpResponseUtils.createResponse(HttpResponseStatus.NOT_FOUND, "404")).addListener(ChannelFutureListener.CLOSE); + return; + } + + RobotContext context = new RobotContext(); + + Param p = new Param(); + p.decode(req); + String data = "ok"; + String message = "success"; + + JsonObject resObj = new JsonObject(); + resObj.addProperty("code", 0); + if (path.equals("/tianye")) { + ByteBuf jsonBuf = req.content(); + String reqString = jsonBuf.toString(CharsetUtil.UTF_8); + log.info("call tianye req:{}", reqString); + JsonElement element = JsonParser.parseString(reqString); + JsonObject obj = (JsonObject) element; + if (element.isJsonObject()) { + String cmd = obj.get("cmd").getAsString(); + switch (cmd) { + case "close_all_tab": { + log.info("close_all_tab"); + CodeService.invokeLater(() -> AthenaContext.ins().getProjectMap().keySet().forEach(projectName -> AgentService.closeAllOpenFilesInProject(AthenaContext.ins().getProjectMap().get(projectName)))); + break; + } + //创建代码或者修改代码 + case "write_code": { + resObj = new WriteCodeHandler().execute(obj, resObj); + break; + } + //创建测试类 + case "generate_test_class": { + String projectName = obj.get("projectName").getAsString(); + String moduleName = obj.get("moduleName").getAsString(); + String promptName = getPromptNameFromJsonObject(obj); + Project project = AthenaContext.ins().getProjectMap().get(projectName); + //如果指定package,则这个package下的所有类都会创建测试类 + String packageName = getPackageNameFromJsonObject(obj); + List list = getClassListFromPackage(packageName, project, obj); + list.stream().forEach(className -> { + log.info("generate_test_class class name:{}", className); + String code = ApplicationManager.getApplication().runReadAction((Computable) () -> { + PsiClass psiClass = PsiClassUtils.findClassByName(project, className); + PsiElement javaFile = psiClass.getParent(); + return javaFile.getText(); + }); + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + JsonObject jsonRes = PromptAndFunctionProcessor.callPrompt(project, promptInfo, ImmutableMap.of("code", code)); + String testClassCode = extractTestClassCodeFromJsonResponse(jsonRes); + AthenaClassInfo info = AthenaCodeService.classInfo(testClassCode); + ApplicationManager.getApplication().invokeLater(() -> { + PsiClass clazz = PsiClassUtils.findClassByName(project, info.getPackagePath() + "." + info.getName()); + if (null == clazz) { + //没有package则直接创建 + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiDirectory directory = PsiClassUtils.getTestSourceDirectory(project, moduleName); + directory = PsiClassUtils.createPackageDirectories(directory, info.getPackagePath()); + PsiClassUtils.createClass(project, info.getName(), testClassCode, false, directory); + log.info("create test class:{} success", info.getName()); + }); + } else { + log.info("class {} already exists", info.getName()); + } + }); + }); + break; + } + //快速修复代码 + case "fix_code": { + processJsonObjectAndFixCode(obj, resObj); + break; + } + //执行代码 + case "run_code": { + ApplicationManager.getApplication().invokeLater(() -> ActionEventUtils.executeDefaultRunAction()); + } + //打开代码 + case "open_code": { + String projectName = obj.get("projectName").getAsString(); + String className = obj.get("className").getAsString(); + ApplicationManager.getApplication().invokeLater(() -> { + JavaClassUtils.openClass(ProjectUtils.projectFromManager(projectName), className); + }); + } + //列出project + case "list_project": { + listProject(ctx, resObj); + return; + } + //列出module + case "list_module": { + listModule(ctx, obj, resObj); + return; + } + //执行java程序 + case "execute_java": { + executeJava(obj); + break; + } + //读取code + case "read_code": { + resObj = new ReadCodeHandler().execute(obj, resObj); + break; + } + //创建包路径 + case "create_package": { + createPackage(obj); + break; + } + case "auto_app": { + // 调用jcommen genreateCodeBase + ProjectUtils projectUtils = new ProjectUtils(); + Project project = ProjectUtils.projectFromManager(); + String projectName = obj.get("projectName").getAsString(); + String groupId = obj.get("groupId").getAsString(); + String author = obj.get("author").getAsString(); + Optional autoAppPath = projectUtils.generateProjectBase(project, projectName, "run.mone", groupId, author); + // openProject + autoAppPath.ifPresent(string -> projectUtils.openProject(project, string)); + break; + } + } + } + sendRes(ctx, resObj); + return; + } + + //mp3 + if (uri.contains("audio")) { + ByteBuf jsonBuf = req.content(); + String base64Data = jsonBuf.toString(CharsetUtil.UTF_8); + byte[] bytes = Base64.getDecoder().decode(base64Data); + AudioInputStream a = AudioSystem.getAudioInputStream(new ByteArrayInputStream(bytes)); + Clip c = AudioSystem.getClip(); + c.open(a); + c.start(); + sendRes(ctx, getObj("ok", "success")); + return; + } + //这里会调用python代码(然后python最后会代用到ai) + if (uri.contains("go")) { + RobotService.consoleMessage(context, RobotReq.builder().param("call go v:" + p.getV()).build()); + String scriptPath = ConfigUtils.getConfig().getMvnPath(); + PythonExecutor.run(scriptPath + "run.sh", p.getV()); + } + //解析出来实际要执行的命令(curl http://127.0.0.1:3458/ai?cmd=在终端执行命令ls -la) + if (uri.contains("ai")) { + RobotService.consoleMessage(context, RobotReq.builder().param("call ai cmd:" + p.getCmd()).build()); + ByteBuf jsonBuf = req.content(); + String jsonStr = jsonBuf.toString(CharsetUtil.UTF_8); + AiReq aiReq = gson.fromJson(jsonStr, AiReq.class); + + String cmd = aiReq.getCmd(); + p.setCmd(cmd); + + if (aiReq.getAi().equals("chatglm")) { + String res = HttpClient.callChatgml(aiReq.getCmd()); + RobotService.consoleMessage(context, RobotReq.builder().param("call glm res:" + res).build()); + String scriptPath = ConfigUtils.getConfig().getMvnPath(); + PythonExecutor.run(scriptPath + "play_run.sh", res); + sendRes(ctx, getObj(res, "success")); + return; + } + + if (aiReq.getAi().equals("chatgpt")) { + String key = ConfigUtils.getConfig().getChatgptKey(); + String proxy = ConfigUtils.getConfig().getChatgptProxy(); + String res = OpenaiCall.call(key, proxy, "%s", aiReq.getCmd()); + RobotService.consoleMessage(context, RobotReq.builder().param("call gpt res:" + res).build()); + String scriptPath = ConfigUtils.getConfig().getMvnPath(); + PythonExecutor.run(scriptPath + "play_run.sh", res); + sendRes(ctx, getObj(res, "success")); + return; + } + + //不执行ai,直接自己解析,方便测试 + else if (cmd.startsWith("run:")) { + RobotService.consoleMessage(context, RobotReq.builder().param("debug pattern").build()); + String[] cmds = cmd.split(":"); + p.setPath(cmds[1]); + if (cmds.length >= 3) { + p.setParam(cmds[2]); + } else { + p.setParam(""); + } + } else { +// Pair res = ChatGptService.callOpenai(Prompt.get("cmd"), cmd); + Pair res = null; + if (res.getKey() != 0) { + RobotService.consoleMessage(context, RobotReq.builder().param(res.getValue()).build()); + FullHttpResponse response = HttpResponseUtils.createResponse(HttpResponseStatus.INTERNAL_SERVER_ERROR, res.getValue()); + ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); + return; + } + RobotService.consoleMessage(context, RobotReq.builder().param("call ai cmd:" + p.getCmd() + " res:" + res).build()); + message = res.getValue(); + Pair pair = p.getPathAndParam(res.getValue()); + p.setPath(pair.getKey()); + p.setParam(pair.getValue()); + } + } + data = RobotService.invoke(p.getPath(), context, RobotReq.builder().param(p.getParam()).build()); + RobotService.consoleMessage(context, RobotReq.builder().param("call robot res:" + data + " param:" + p.getParam() + " method:" + p.getPath()).build()); + MutableObject mo = new MutableObject(data); + SafeRun.run(() -> { + if (null != mo.getValue() && mo.getValue().toString().length() > 0) { + RobotService.consoleMessage(context, RobotReq.builder().param("say res:" + mo.getValue()).build()); + String scriptPath = ConfigUtils.getConfig().getMvnPath(); + PythonExecutor.run(scriptPath + "play_run.sh", mo.getValue().toString()); + } + }); + JsonObject obj = getObj(data, message); // 创建http响应 - sendRes(ctx, new JsonObject()); + sendRes(ctx, obj); + } + + + //执行java代码(比如创建sql 比如创建orm先关的类),有些代码最好是生成的 + private static void executeJava(JsonObject obj) { + log.info("execute java obj:{}", obj); + String className = obj.get("className").getAsString(); + String type = obj.get("type").getAsString(); + JsonObject jsonObj = new JsonObject(); + if (type.equals("create_table")) { + String sql = obj.get("sql").getAsString(); + jsonObj.addProperty("sql", sql); + } else if (type.equals("create_code")) { + if (obj.has("tableName")) { + jsonObj.addProperty("tableName", obj.get("tableName").getAsString()); + } + if (obj.has("pojoName")) { + jsonObj.addProperty("pojoName", obj.get("pojoName").getAsString()); + } + } + jsonObj.addProperty("type", type); + String param = new String(Base64.getEncoder().encode(GsonUtils.gson.toJson(jsonObj).getBytes())); + ActionEventUtils.setupAndExecuteJavaAppConfiguration(className, param, ProjectUtils.projectFromManager(obj.get("projectName").getAsString())); + } + + private void listProject(ChannelHandlerContext ctx, JsonObject resObj) { + resObj.add("data", gson.toJsonTree(ProjectUtils.listOpenProjects())); + sendRes(ctx, resObj); + } + + private void listModule(ChannelHandlerContext ctx, JsonObject obj, JsonObject resObj) { + String projectName = obj.get("projectName").getAsString(); + resObj.add("data", gson.toJsonTree(ProjectUtils.listAllModules(ProjectUtils.projectFromManager(projectName)))); + sendRes(ctx, resObj); + } + + private static void createPackage(JsonObject obj) { + String projectName = obj.get("projectName").getAsString(); + String moduleName = obj.get("moduleName").getAsString(); + String packageName = obj.get("packageName").getAsString(); + CodeService.createPackageInModule(ProjectUtils.getModuleWithName(ProjectUtils.projectFromManager(projectName), moduleName), packageName); + } + + private static void processJsonObjectAndFixCode(JsonObject obj, JsonObject resObj) { + boolean blockOnFailure = false; + try { + // 找到已生成的pojo or service or controller + String projectName = obj.get("projectName").getAsString(); +// String className = obj.get("className").getAsString(); + JsonArray classList = obj.get("classList").getAsJsonArray(); + String packageName = obj.get("packageName").getAsString(); + JsonElement blockJson = obj.get("blockOnFailure"); + if (blockJson != null && "true".equals(blockJson.getAsString())) { + blockOnFailure = true; + } + if (StringUtils.isBlank(projectName)) { + return; + } + for (int i = 0; i < classList.size(); i++) { + String clsName = getFQCN(packageName, classList.get(i).getAsString()); + String code = getCode(projectName, clsName); + // 尝试quick fix + // TODO: not working for now + // ApplicationManager.getApplication().invokeLater(() -> CodeService.tryQuickFix(code, obj, projectName, className)); + // 尝试基于parse的fix + ApplicationManager.getApplication().invokeLater(() -> CodeService.tryParserBasedFix(code, projectName, clsName)); + } + resObj.addProperty("success", "true"); + return; + } catch (Exception e) { + log.error("Error while try to fix code, nested exception is:", e); + } + // HINT: whether to block on failure + if (!blockOnFailure) { + resObj.addProperty("success", "true"); + } + } + + @NotNull + private static List getClassListFromPackage(String packageName, Project project, JsonObject obj) { + List list = null; + if (StringUtils.isNotEmpty(packageName)) { + list = ApplicationManager.getApplication().runReadAction((Computable>) () -> PackageUtils.getClassList(project, packageName)); + } + if (null == list) { + String className = obj.get("className").getAsString(); + list = Lists.newArrayList(className); + } + return list; + } + + private static String getPromptNameFromJsonObject(JsonObject obj) { + String promptName = "test_class_code"; + if (obj.has("promptName")) { + promptName = obj.get("promptName").getAsString(); + } + return promptName; + } + + private static String getPackageNameFromJsonObject(JsonObject obj) { + String packageName = ""; + if (obj.has("packageName")) { + packageName = obj.get("packageName").getAsString(); + } + return packageName; + } + + private static String extractTestClassCodeFromJsonResponse(JsonObject jsonRes) { + String testClassCode = jsonRes.get("data").getAsString(); + testClassCode = MarkDownUtils.extractCodeBlock(testClassCode); + return testClassCode; + } + + private static String getCode(String projectName, String className) { + try { + return ReadAction.compute(() -> { + // 确保我们在正确的上下文中 + if (!ApplicationManager.getApplication().isReadAccessAllowed()) { + throw new IllegalStateException("Read access is not allowed"); + } + PsiClass psiClass = PsiClassUtils.findClassByName(ProjectUtils.projectFromManager(projectName), className); + return psiClass.getText(); + }); + } catch (Throwable e) { + log.error("failed to get code for class: {}, in project:{}", className, projectName); + return ""; + } + } + + private static String getFQCN(String packageName, String className) { + return StringUtils.joinWith(".", packageName, className); } private void sendRes(ChannelHandlerContext ctx, JsonObject obj) { @@ -37,4 +439,5 @@ private static JsonObject getObj(String data, String message) { return obj; } + } \ No newline at end of file diff --git a/athena-all/src/main/java/run/mone/ultraman/UltramanHttpServer.java b/athena-all/src/main/java/run/mone/ultraman/UltramanHttpServer.java deleted file mode 100644 index 553113843..000000000 --- a/athena-all/src/main/java/run/mone/ultraman/UltramanHttpServer.java +++ /dev/null @@ -1,60 +0,0 @@ -package run.mone.ultraman; - -import io.netty.bootstrap.ServerBootstrap; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOption; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseEncoder; -import io.netty.handler.codec.http.cors.CorsConfig; -import io.netty.handler.codec.http.cors.CorsConfigBuilder; -import io.netty.handler.codec.http.cors.CorsHandler; -import io.netty.handler.stream.ChunkedWriteHandler; - -public class UltramanHttpServer { - - private int port; - - public UltramanHttpServer(int port) { - this.port = port; - } - - public void run() throws Exception { - EventLoopGroup bossGroup = new NioEventLoopGroup(); - EventLoopGroup workerGroup = new NioEventLoopGroup(); - try { - ServerBootstrap b = new ServerBootstrap(); - b.group(bossGroup, workerGroup) - .channel(NioServerSocketChannel.class) - .childHandler(new ChannelInitializer() { - public void initChannel(SocketChannel ch) throws Exception { - ch.pipeline().addLast("http-decoder", new HttpRequestDecoder()); - ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65535)); - ch.pipeline().addLast("http-encoder", new HttpResponseEncoder()); - ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler()); - // Configure CORS - CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin() - .allowedRequestHeaders("X-Requested-With", "Content-Type", "Accept", "Origin", "Authorization", "Referer", "sec-ch-ua", "sec-ch-ua-mobile", "sec-ch-ua-platform") - .allowedRequestMethods(HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE, HttpMethod.OPTIONS) - .build(); - ch.pipeline().addLast("http-cors", new CorsHandler(corsConfig)); - ch.pipeline().addLast("http-server", new HttpServerHandler()); - } - }) - .option(ChannelOption.SO_BACKLOG, 128) - .childOption(ChannelOption.SO_KEEPALIVE, true); - ChannelFuture f = b.bind("0.0.0.0", port).sync(); - f.channel().closeFuture().sync(); - } finally { - bossGroup.shutdownGracefully(); - workerGroup.shutdownGracefully(); - } - } - -} \ No newline at end of file diff --git a/athena-all/src/main/java/run/mone/ultraman/action/AthenaStatusBarAction.java b/athena-all/src/main/java/run/mone/ultraman/action/AthenaStatusBarAction.java new file mode 100644 index 000000000..1aeaae911 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/action/AthenaStatusBarAction.java @@ -0,0 +1,21 @@ +package run.mone.ultraman.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import run.mone.ultraman.statusbar.AthenaStatusBarWidget; +import run.mone.ultraman.statusbar.PopUpReq; + +/** + * @author HawickMason@xiaomi.com + * @date 6/22/24 15:16 + */ +public class AthenaStatusBarAction extends AnAction { + + @Override + public void actionPerformed(@NotNull AnActionEvent actionEvent) { + Project project = actionEvent.getProject(); + AthenaStatusBarWidget.popUp(project, null, null, PopUpReq.builder().build()); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/action/RegenerateCompletionAction.java b/athena-all/src/main/java/run/mone/ultraman/action/RegenerateCompletionAction.java new file mode 100644 index 000000000..40cbe0ae7 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/action/RegenerateCompletionAction.java @@ -0,0 +1,46 @@ +package run.mone.ultraman.action; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.editor.Editor; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import run.mone.ultraman.manager.InlayHintManager; +import run.mone.ultraman.listener.AthenaApplicationActivationListener; + +/** + * @author zhangxiaowei6 + * @Date 2024/6/20 14:36 + */ + +@Slf4j +public class RegenerateCompletionAction extends AnAction { + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + // 获取编辑器实例 + Editor editor = e.getData(CommonDataKeys.EDITOR); + if (editor == null) { + return; + } + // 此时如果有inlay内容则用户输入后dispose + InlayHintManager.ins().dispose(text -> { + if (StringUtils.isNotEmpty(text)) { + CodeService.deleteCode(editor); + CodeService.formatCode(editor.getProject()); + } + }); + // 再次触发 + AthenaApplicationActivationListener.handlePluginInEditor(editor); + } + + @Override + public void update(@NotNull AnActionEvent e) { + // 设置动作在编辑器中可用 + Editor editor = e.getData(CommonDataKeys.EDITOR); + e.getPresentation().setEnabledAndVisible(editor != null); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/ai/MyCompletionContributor.java b/athena-all/src/main/java/run/mone/ultraman/ai/MyCompletionContributor.java index c3eee7b75..a18d42a58 100644 --- a/athena-all/src/main/java/run/mone/ultraman/ai/MyCompletionContributor.java +++ b/athena-all/src/main/java/run/mone/ultraman/ai/MyCompletionContributor.java @@ -7,8 +7,8 @@ import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.*; import com.intellij.util.ProcessingContext; -import run.mone.m78.ip.common.ProjectCache; -import run.mone.m78.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.common.ProjectCache; +import com.xiaomi.youpin.tesla.ip.service.CodeService; import org.jetbrains.annotations.NotNull; import java.util.List; diff --git a/athena-all/src/main/java/run/mone/ultraman/background/AiBackgroundTask.java b/athena-all/src/main/java/run/mone/ultraman/background/AiBackgroundTask.java new file mode 100644 index 000000000..483582af6 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/background/AiBackgroundTask.java @@ -0,0 +1,44 @@ +package run.mone.ultraman.background; + +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * @author goodjava@qq.com + * @date 2024/6/1 21:10 + */ +public class AiBackgroundTask extends Task.Backgroundable { + + private volatile boolean isCancelled = false; + + private CountDownLatch latch = new CountDownLatch(1); + + public AiBackgroundTask(Project project, String title) { + super(project, title); + } + + @Override + public void run(ProgressIndicator progressIndicator) { + progressIndicator.setIndeterminate(false); + progressIndicator.setFraction(0.0); + while (!isCancelled && !progressIndicator.isCanceled()) { + try { + latch.await(1, TimeUnit.MINUTES); + } catch (Throwable ignore) { + + } finally { + break; + } + } + } + + public void cancel() { + isCancelled = true; + latch.countDown(); + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/background/AiCode.java b/athena-all/src/main/java/run/mone/ultraman/background/AiCode.java index 522d483a3..010cdc51b 100644 --- a/athena-all/src/main/java/run/mone/ultraman/background/AiCode.java +++ b/athena-all/src/main/java/run/mone/ultraman/background/AiCode.java @@ -3,12 +3,13 @@ import com.google.gson.Gson; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.bo.AiMessage; -import run.mone.m78.ip.bo.MessageConsumer; -import run.mone.m78.ip.common.ChromeUtils; -import run.mone.m78.ip.common.Safe; -import run.mone.m78.ip.util.UltramanConsole; +import com.xiaomi.youpin.tesla.ip.bo.AiMessage; +import com.xiaomi.youpin.tesla.ip.bo.MessageConsumer; +import com.xiaomi.youpin.tesla.ip.common.ChromeUtils; +import com.xiaomi.youpin.tesla.ip.common.Safe; +import com.xiaomi.youpin.tesla.ip.util.UltramanConsole; import lombok.Data; +import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; diff --git a/athena-all/src/main/java/run/mone/ultraman/background/AthenaEditorTask.java b/athena-all/src/main/java/run/mone/ultraman/background/AthenaEditorTask.java index 6f76fb1fd..6f0c10d3e 100644 --- a/athena-all/src/main/java/run/mone/ultraman/background/AthenaEditorTask.java +++ b/athena-all/src/main/java/run/mone/ultraman/background/AthenaEditorTask.java @@ -5,11 +5,11 @@ import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.NlsContexts; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.MessageConsumer; -import run.mone.m78.ip.bo.PromptContext; -import run.mone.m78.ip.service.CodeService; -import run.mone.m78.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.MessageConsumer; +import com.xiaomi.youpin.tesla.ip.bo.PromptContext; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.PromptService; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; diff --git a/athena-all/src/main/java/run/mone/ultraman/background/AthenaTask.java b/athena-all/src/main/java/run/mone/ultraman/background/AthenaTask.java index 6cb86f1fe..fd73e8a0b 100644 --- a/athena-all/src/main/java/run/mone/ultraman/background/AthenaTask.java +++ b/athena-all/src/main/java/run/mone/ultraman/background/AthenaTask.java @@ -1,34 +1,54 @@ package run.mone.ultraman.background; import com.google.common.base.Function; +import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.base.Stopwatch; +import com.google.common.collect.Sets; +import com.google.gson.JsonObject; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.NlsContexts; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.ModelRes; -import run.mone.m78.ip.bo.PromptContext; -import run.mone.m78.ip.bo.ZAddrRes; -import run.mone.m78.ip.bo.robot.AiChatMessage; -import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; -import run.mone.m78.ip.bo.robot.Role; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.service.CodeService; -import run.mone.m78.ip.util.UltramanConsole; +import com.xiaomi.youpin.tesla.ip.bo.*; +import com.xiaomi.youpin.tesla.ip.bo.robot.AiChatMessage; +import com.xiaomi.youpin.tesla.ip.bo.robot.ProjectAiMessageManager; +import com.xiaomi.youpin.tesla.ip.bo.robot.Role; +import com.xiaomi.youpin.tesla.ip.bo.z.ZKnowledgeRes; +import com.xiaomi.youpin.tesla.ip.common.NotificationCenter; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.common.Safe; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.util.EditorUtils; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.util.UltramanConsole; +import lombok.Getter; import lombok.Setter; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.mutable.MutableBoolean; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; - +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.bo.AthenaClassInfo; +import run.mone.ultraman.bo.AthenaMethodInfo; +import run.mone.ultraman.bo.CodeReq; +import run.mone.ultraman.common.CodeUtils; +import run.mone.ultraman.common.ImportCode; +import run.mone.ultraman.service.AthenaCodeService; +import run.mone.ultraman.state.PromptAndFunctionProcessor; + +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** @@ -51,12 +71,17 @@ public class AthenaTask extends Task.Backgroundable { private String text; - private Map params; + @Getter + private Map params = new HashMap<>(); @Setter private boolean format = true; @Setter + private GenerateCodeReq req; + + @Setter + @Getter private PromptContext promptContext; private static final String METHOD_CONTEXT = "method_context"; @@ -65,13 +90,16 @@ public class AthenaTask extends Task.Backgroundable { private static final String RESOURCE_CONTEXT = "resource_context"; - private static final String CONTEXT = "context"; + private static final String PO_CONTEXT = "po_context"; + + public static final String CONTEXT = "context"; //chat(聊天窗口) editor(ide中) @Setter private String type = "chat"; @Setter + @Getter private Runnable initRunnable; @@ -83,6 +111,10 @@ public AthenaTask(@Nullable Project project, @NlsContexts.ProgressTitle @NotNull this.params = params; } + public AthenaTask(@Nullable Project project, @NlsContexts.ProgressTitle @NotNull String title) { + super(project, title); + } + @SneakyThrows @Override public void run(@NotNull ProgressIndicator progressIndicator) { @@ -90,15 +122,16 @@ public void run(@NotNull ProgressIndicator progressIndicator) { initRunnable.run(); } + //参数的一些替换,比如翻译用中文 + extractPrefixedUserLabelsToParams(); + String scope = ""; if (null != this.promptContext) { - callResourceContext(); - callMethodContext(); - callModuleContext(); + initContexts(); scope = this.promptContext.getScope(); } - callContextSize(); + calculateAndOptimizeRequestSize(); ZAddrRes zAddrRes = Prompt.zAddrRes(); if (CollectionUtils.isNotEmpty(zAddrRes.getModels())) { @@ -118,15 +151,64 @@ public void run(@NotNull ProgressIndicator progressIndicator) { CountDownLatch countDownLatch = new CountDownLatch(1); UltramanConsole.append(project, "\ncall prompt begin:" + promptName + " scope:" + scope); AiCode aiCode = getAiCode(progressIndicator, countDownLatch); + Stopwatch sw = Stopwatch.createStarted(); - //一点一点的生成代码 - CodeService.generateCodeWithAi5(GenerateCodeReq.builder().format(format).promptName(promptName).project(project).build(), project, promptName, new String[]{text}, params, (p, code) -> { - }, aiCode); - //最多等1分钟 - countDownLatch.await(3, TimeUnit.MINUTES); - String text = aiCode.getMarkDownText(); + String text = ""; + if (!LabelUtils.isOpen(this.project, req.getPromptInfo(), "call_json")) { + //一点一点的生成代码 + CodeService.generateCodeWithAi5(GenerateCodeReq.builder().format(format).promptName(promptName).project(project).build(), project, promptName, new String[]{text}, params, (p, code) -> { + }, aiCode); + //最多等3分钟 + countDownLatch.await(5, TimeUnit.MINUTES); + text = aiCode.getMarkDownText(); + } else { + //直接调用返回json的接口(目前代码补全会走到这里) + JsonObject obj = PromptAndFunctionProcessor.callPrompt(this.project, req.getPromptInfo(), convertMap(params)); + log.info("{}", obj); + text = obj.get("code").getAsString(); + int offset = EditorUtils.moveCursorToMethodEndIfOutside(req.getEditor(), req.getPsiMethod(), req.getOffset()); + CodeService.insertCode(this.project, text, false, offset, req.getEditor()); + } + // 上报生成信息 + String finalText = text; UltramanConsole.append(project, "call prompt finish:" + promptName + " use time:" + sw.elapsed(TimeUnit.SECONDS) + "s\n"); ProjectAiMessageManager.getInstance().appendMsg(project, AiChatMessage.builder().id(aiCode.getMessageId()).role(Role.assistant).message(text).data(text).build()); + + CodeUtils.uploadCodeGenInfo(getInfo(finalText)); + } + + private M78CodeGenerationInfo getInfo(String code){ + M78CodeGenerationInfo info = new M78CodeGenerationInfo(); + info.setCodeLinesCount(CodeUtils.getLineCnt(code, false)); + info.setAnnotation(CodeUtils.checkLineStartsWithComment(this.req.getChatComment())); + info.setProjectName(this.project.getName()); + info.setClassName(this.req.getClassName()); + info.setMethodName("GENERATED"); + return info; + } + + public void initContexts() { + Safe.run(() -> callResourceContext()); + Safe.run(() -> callPoContext()); + Safe.run(() -> callMethodContext()); + Safe.run(() -> callModuleContext()); + } + + private void extractPrefixedUserLabelsToParams() { + Map userLabels = req.getPromptInfo().getLabels(); + if (MapUtils.isNotEmpty(userLabels)) { + userLabels.entrySet().stream().forEach(it -> { + if (it.getKey().startsWith("__")) { + this.params.put(it.getKey(), it.getValue()); + } + }); + } + } + + //把一个Map转换为Map(method) + public Map convertMap(Map stringMap) { + return stringMap.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> (Object) e.getValue())); } @@ -138,13 +220,80 @@ public void run(@NotNull ProgressIndicator progressIndicator) { * @return */ @NotNull - private AiCode getAiCode(@NotNull ProgressIndicator progressIndicator, CountDownLatch countDownLatch) { - return null; + protected AiCode getAiCode(@NotNull ProgressIndicator progressIndicator, CountDownLatch countDownLatch) { + //方法注释 + if (type.equals("method_comment")) { + return new AiCode(progressIndicator, countDownLatch, this.project, message -> { + ImportCode importCode = new ImportCode(); + importCode.setProject(project); + importCode.setEditor(promptContext.getEditor()); + + if (message.getType().equals(AiMessageType.begin)) { + ApplicationManager.getApplication().invokeLater(() -> { + CodeService.moveToMethodAndInsertLine(project); + }); + } + + if (message.getType().equals(AiMessageType.process)) { + importCode.append(message.getText()); + } + }); + } + //在编辑器添加代码(添加到ide中) + else if (type.equals("edit")) { + ImportCode importCode = new ImportCode(); + importCode.setProject(project); + importCode.setEditor(promptContext.getEditor()); + return new AiCode(progressIndicator, countDownLatch, this.project, message -> { + //开始(调整光标位置) + if (message.getType().equals(AiMessageType.begin)) { + String comment = params.get("code"); + ProjectAiMessageManager.getInstance().appendMsg(project, AiChatMessage.builder().role(Role.user).message(comment).data(comment).build()); + + ApplicationManager.getApplication().invokeLater(() -> { + CodeService.moveCaretToEndOfLine(this.promptContext.getEditor()); + CodeService.writeCode2(project, this.promptContext.getEditor(), "\n"); + }); + } + //处理中(添加内容到ide) + if (message.getType().equals(AiMessageType.process)) { + importCode.append(message.getText()); + } + }); + } else { + return new AiCode(progressIndicator, countDownLatch, this.project); + } } //计算请求的size,有写大小需要优化(最终大小需要低于3500) - private void callContextSize() { + public void calculateAndOptimizeRequestSize() { + String resourceContext = this.params.getOrDefault(RESOURCE_CONTEXT, ""); + String poContext = this.params.getOrDefault(PO_CONTEXT, ""); + String moduleContext = this.params.getOrDefault(MODULE_CONTEXT, ""); + String methodContext = this.params.getOrDefault(METHOD_CONTEXT, ""); + //prompt的长度 + int promptSize = 1460; + + int i = resourceContext.length() + methodContext.length() + moduleContext.length() + promptSize; + NotificationCenter.notice(this.project, String.format("Athena Task call size resource:%s class:%s module:%s prompt len:%s total:%s", + resourceContext.length(), methodContext.length(), moduleContext.length(), promptSize, i + ), true); + + if (i > AthenaContext.ins().getMaxTokenNum()) { + moduleContext = ""; + } + + //拼接处完整的上下文 + this.params.put(CONTEXT, Joiner.on("\n\n").join(resourceContext, poContext, moduleContext)); + + if (this.params.get(CONTEXT).length() > 30) { + UltramanConsole.append(this.project, "context:\n" + this.params.get(CONTEXT)); + } + } + + public String getContext() { + return this.params.getOrDefault(CONTEXT, ""); } @@ -157,15 +306,99 @@ private void callContextSize() { }; private void callModuleContext() { - + if ((null != this.promptContext.getScope()) && (this.promptContext.getScope().equals("module") || this.promptContext.getScope().equals("project"))) { + String moduleName = ""; + if (this.promptContext.getScope().equals("module")) { + moduleName = this.promptContext.getModule(); + } + //计算module中的context + List list = AthenaCodeService.getCodeList(CodeReq.builder().projectName(this.promptContext.getProject()).moduleName(moduleName).requirement(promptContext.getComment()).build()); + + if (null != this.promptContext.getResourceBeanList() && (this.promptContext.getResourceBeanList().size() > 0) && (null != list && list.size() > 0)) { + list = list.stream().filter(it -> { + MutableBoolean mb = new MutableBoolean(true); + Safe.run(() -> { + AthenaClassInfo ci = AthenaCodeService.classInfo(it.getContent()); + boolean v = promptContext.getResourceBeanList().stream().map(f).collect(Collectors.toList()).contains(ci.getName()) + || + (Sets.intersection(Sets.newHashSet(promptContext.getResourceBeanList().stream().map(f).collect(Collectors.toList())), Sets.newHashSet(ci.getInterfaceList())).size() > 0); + mb.setValue(!v); + }); + return (boolean) mb.getValue(); + }).collect(Collectors.toList()); + } + //如果codeserver 有相关代码,则相信code server 中的代码(不然数量太大,很难处理) + String moduleContext = ""; + if (null != list && list.size() > 0) { + int limitNum = AthenaContext.ins().gptModel().getModuleClassNum(); + moduleContext = list.stream().limit(limitNum).map(it -> it.getContent()).collect(Collectors.joining("\n")); + UltramanConsole.append(this.project, "\nmodule context:" + moduleContext + "\n"); + } + this.params.put(MODULE_CONTEXT, moduleContext); + } } //引入一些class内部的方法(能起到一定的教学作用) private void callMethodContext() { + //计算引入哪些方法(会调用chatgpt) + if (null != this.promptContext.getMethodCodeList()) { + List list = this.promptContext.getMethodCodeList(); + int methodLimitNum = 2; + if (!AthenaContext.ins().gptModel().isOptimizeTokens()) { + methodLimitNum = 10; + list.stream().forEach(it -> it.setScore(100)); + } else { + list.stream().forEach(it -> { + try { + Map map = new HashMap<>(); + map.put("method", it.getCode()); + map.put("requirement", promptContext.getComment()); + //这里有个问题,调用次数过多,会超过某些module的限制 + int value = Integer.valueOf(AthenaCodeService.callProxy(this.project, map, "requirement", 5).value()); + it.setScore(value); + UltramanConsole.append(this.project, "method score:" + value + "\n" + it.getCode() + "\n\n"); + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (InterruptedException e) { + System.out.println(e.getMessage()); + } + } catch (Throwable ex) { + ex.printStackTrace(); + } + }); + } + + String fieldCode = this.promptContext.getFieldCodeList().stream().map(it -> it.getCode() + "\n").collect(Collectors.joining()); + List newList = list.stream().sorted((a, b) -> b.getScore() - a.getScore()).filter(it -> it.getScore() > 30).collect(Collectors.toList()); + if (newList.size() == 0) { + newList = list.stream().sorted((a, b) -> b.getScore() - a.getScore()).limit(1).collect(Collectors.toList()); + } else { + newList = list.stream().limit(methodLimitNum).collect(Collectors.toList()); + } + String classCode = newList.stream().map(it -> it.getCode()).collect(Collectors.joining("\n\n")); + classCode = "public class " + promptContext.getClazzName() + "{\n" + fieldCode + classCode + "\n}"; + UltramanConsole.append(this.project, "class:\n" + classCode + "\n" + "size:" + classCode.length() + "\n\n"); + this.params.put("class", classCode); + this.params.put(METHOD_CONTEXT, classCode); + } } private void callResourceContext() { + //计算引入哪些资源(会调用chatgpt) + if (null != this.promptContext.getResourceCode()) { + //获取@Resource引入的代码 + String resource = PromptService.getResourceFromAi(this.project, this.params, this.promptContext, this.promptContext.getResourceCode()); + this.params.put(RESOURCE_CONTEXT, resource); + UltramanConsole.append(project, "resource:\n" + resource + "\n"); + } + } + //计算po的上下文引入 + private void callPoContext() { + if (null != this.promptContext.getPoClassInfos()) { + this.params.put(PO_CONTEXT, Joiner.on("\n").join(this.promptContext.getPoClassInfos().stream().map(it -> it.getCode()).collect(Collectors.toList()))); + UltramanConsole.append(project, "po:\n" + this.params.get(PO_CONTEXT) + "\n"); + } } diff --git a/athena-all/src/main/java/run/mone/ultraman/background/BotTask.java b/athena-all/src/main/java/run/mone/ultraman/background/BotTask.java new file mode 100644 index 000000000..163df35b1 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/background/BotTask.java @@ -0,0 +1,26 @@ +package run.mone.ultraman.background; + +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.NlsContexts; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author goodjava@qq.com + * @date 2024/6/2 22:29 + */ +public class BotTask extends Task.Backgroundable { + + public BotTask(@Nullable Project project, @NlsContexts.ProgressTitle @NotNull String title) { + super(project, title); + } + + @Override + public void run(@NotNull ProgressIndicator indicator) { + indicator.setIndeterminate(false); + + + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/background/EditorAiCode.java b/athena-all/src/main/java/run/mone/ultraman/background/EditorAiCode.java index a2d1779e4..74130cce3 100644 --- a/athena-all/src/main/java/run/mone/ultraman/background/EditorAiCode.java +++ b/athena-all/src/main/java/run/mone/ultraman/background/EditorAiCode.java @@ -2,9 +2,9 @@ import com.google.gson.Gson; import com.intellij.openapi.progress.ProgressIndicator; -import run.mone.m78.ip.bo.AiMessage; -import run.mone.m78.ip.bo.MessageConsumer; -import run.mone.m78.ip.common.Safe; +import com.xiaomi.youpin.tesla.ip.bo.AiMessage; +import com.xiaomi.youpin.tesla.ip.bo.MessageConsumer; +import com.xiaomi.youpin.tesla.ip.common.Safe; import lombok.extern.slf4j.Slf4j; import java.time.Duration; diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/AthenaClassInfo.java b/athena-all/src/main/java/run/mone/ultraman/bo/AthenaClassInfo.java index e3fc40f2f..aa0979af3 100644 --- a/athena-all/src/main/java/run/mone/ultraman/bo/AthenaClassInfo.java +++ b/athena-all/src/main/java/run/mone/ultraman/bo/AthenaClassInfo.java @@ -16,6 +16,8 @@ public class AthenaClassInfo { private String name; + private String packagePath; + private String classCode; private String md5; @@ -24,7 +26,13 @@ public class AthenaClassInfo { private List publicMethodList; + private List imports; + @Builder.Default private List interfaceList = new ArrayList<>(); + public String getClassName() { + return this.getPackagePath() + "." + this.getName(); + } + } diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/DesensitizeReq.java b/athena-all/src/main/java/run/mone/ultraman/bo/DesensitizeReq.java new file mode 100644 index 000000000..5388d45ec --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/DesensitizeReq.java @@ -0,0 +1,25 @@ +package run.mone.ultraman.bo; + +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2024/2/4 16:22 + */ +@Data +@Builder +public class DesensitizeReq implements Serializable { + + private String text; + + private String langType; + + private boolean aiDesensitizeFlag; + + private String zzToken; + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/PoClassInfo.java b/athena-all/src/main/java/run/mone/ultraman/bo/PoClassInfo.java new file mode 100644 index 000000000..18ae99e84 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/bo/PoClassInfo.java @@ -0,0 +1,18 @@ +package run.mone.ultraman.bo; + +import lombok.Builder; +import lombok.Data; + +/** + * @author goodjava@qq.com + * @date 2024/1/29 14:24 + */ +@Data +@Builder +public class PoClassInfo { + + private String name; + + private String code; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/bo/Version.java b/athena-all/src/main/java/run/mone/ultraman/bo/Version.java index 51dbf716c..1c0432b2e 100644 --- a/athena-all/src/main/java/run/mone/ultraman/bo/Version.java +++ b/athena-all/src/main/java/run/mone/ultraman/bo/Version.java @@ -1,15 +1,30 @@ package run.mone.ultraman.bo; +import com.xiaomi.youpin.tesla.ip.common.VersionUtil; +import lombok.Data; + import java.io.Serializable; /** * @author goodjava@qq.com * @date 2023/6/7 14:06 */ +@Data public class Version implements Serializable { + private String ATHENA_TYPE = "IDEA"; + @Override public String toString() { - return "0.0.1:2024-01-12-1"; + return ATHENA_TYPE + ":" + getVersion(); + } + + public String getVersion() { + return VersionUtil.getAthenaPluginVersion(); } + + public String getName() { + return ATHENA_TYPE; + } + } diff --git a/athena-all/src/main/java/run/mone/ultraman/common/ActionEventUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/ActionEventUtils.java index 71ca1055e..1c87f4c38 100644 --- a/athena-all/src/main/java/run/mone/ultraman/common/ActionEventUtils.java +++ b/athena-all/src/main/java/run/mone/ultraman/common/ActionEventUtils.java @@ -1,10 +1,21 @@ package run.mone.ultraman.common; +import com.intellij.execution.Executor; +import com.intellij.execution.ExecutorRegistry; +import com.intellij.execution.RunManager; +import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.application.ApplicationConfiguration; +import com.intellij.execution.application.ApplicationConfigurationType; +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.ExecutionEnvironmentBuilder; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.ui.speedSearch.SpeedSearchSupply; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author goodjava@qq.com @@ -13,6 +24,105 @@ public class ActionEventUtils { + /** + * 进行 Java 应用配置的设置与执行 + * 获取数据上下文和项目 + * 创建运行管理器、配置工厂、配置设置等 + * 设置配置的主类名和程序参数 + * 添加和选择配置 + * 获取执行器,构建执行环境 + * 获取程序运行器,若不为空则异步执行 + */ + public static void setupAndExecuteJavaAppConfiguration(String className, String params, Project _project) { + Project project = null; + + // 获取当前的数据上下文 + if (null == _project) { + DataContext dataContext = DataManager.getInstance().getDataContext(); + project = CommonDataKeys.PROJECT.getData(dataContext); + } else { + project = _project; + } + + if (project == null) { + return; // 如果没有项目,直接返回 + } + + // 获取 RunManager + RunManager runManager = RunManager.getInstance(project); + + // 创建一个新的 Java 应用程序运行配置 + ConfigurationFactory factory = ApplicationConfigurationType.getInstance().getConfigurationFactories()[0]; + RunnerAndConfigurationSettings configurationSettings = runManager.createConfiguration("MioneRun", factory); + ApplicationConfiguration applicationConfiguration = (ApplicationConfiguration) configurationSettings.getConfiguration(); + + // 设置 main 函数的参数 + applicationConfiguration.setMainClassName(className); // 设置主类名 + applicationConfiguration.setProgramParameters(params); // 设置参数 + + // 将新的运行配置添加到 RunManager + runManager.addConfiguration(configurationSettings); + runManager.setSelectedConfiguration(configurationSettings); + + Executor executor = ExecutorRegistry.getInstance().getExecutorById(DefaultRunExecutor.EXECUTOR_ID); + + // 创建 ExecutionEnvironment + ExecutionEnvironmentBuilder builder = ExecutionEnvironmentBuilder.create(executor, configurationSettings.getConfiguration()); + ExecutionEnvironment environment = builder.build(); + + // 获取 ProgramRunner + ProgramRunner runner = ProgramRunner.getRunner(DefaultRunExecutor.EXECUTOR_ID, environment.getRunProfile()); + + if (runner != null) { + // 在事件调度线程中执行运行配置 + ApplicationManager.getApplication().invokeLater(() -> { + try { + runner.execute(environment); + } catch (Exception e) { + e.printStackTrace(); + } + }); + } + } + + + /** + * 执行默认的运行操作。 + * 首先获取当前的数据上下文,然后获取默认的运行动作。 + * 如果该动作存在,则创建一个动作事件并执行该动作。 + */ + public static void executeDefaultRunAction() { + // 获取当前的数据上下文 + DataContext dataContext = DataManager.getInstance().getDataContext(); + // 获取 "Run" 功能对应的 Action + AnAction runAction = ActionManager.getInstance().getAction(IdeActions.ACTION_DEFAULT_RUNNER); + // 模拟触发 "Run" 功能的 Action + if (runAction != null) { + AnActionEvent event = AnActionEvent.createFromDataContext( + ActionPlaces.UNKNOWN, null, dataContext + ); + runAction.actionPerformed(event); + } + } + + /** + * 启动调试器的方法。首先获取当前数据上下文,然后获取默认的调试器动作。如果该动作存在,则创建一个动作事件并执行该动作。 + */ + public static void startDebugger() { + // 获取当前的数据上下文 + DataContext dataContext = DataManager.getInstance().getDataContext(); + // 获取 "Run" 功能对应的 Action + AnAction runAction = ActionManager.getInstance().getAction(IdeActions.ACTION_DEFAULT_DEBUGGER); + // 模拟触发 "Run" 功能的 Action + if (runAction != null) { + AnActionEvent event = AnActionEvent.createFromDataContext( + ActionPlaces.UNKNOWN, null, dataContext + ); + runAction.actionPerformed(event); + } + } + + public static AnActionEvent createAnAction(Project project, String data) { // 创建一个新的 Presentation 对象 Presentation presentation = new Presentation(); diff --git a/athena-all/src/main/java/run/mone/ultraman/common/Code.java b/athena-all/src/main/java/run/mone/ultraman/common/Code.java index f01dca91a..6a09111d1 100644 --- a/athena-all/src/main/java/run/mone/ultraman/common/Code.java +++ b/athena-all/src/main/java/run/mone/ultraman/common/Code.java @@ -9,8 +9,8 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.service.CodeService; import lombok.Data; import org.apache.commons.lang3.StringUtils; diff --git a/athena-all/src/main/java/run/mone/ultraman/common/CodeUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/CodeUtils.java index 6af6d2ea2..4e402f56b 100644 --- a/athena-all/src/main/java/run/mone/ultraman/common/CodeUtils.java +++ b/athena-all/src/main/java/run/mone/ultraman/common/CodeUtils.java @@ -1,5 +1,19 @@ package run.mone.ultraman.common; +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.xiaomi.youpin.infra.rpc.Result; +import com.xiaomi.youpin.tesla.ip.bo.Action; +import com.xiaomi.youpin.tesla.ip.bo.M78CodeGenerationInfo; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.M78Service; +import lombok.extern.slf4j.Slf4j; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.bo.Version; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -8,10 +22,13 @@ * @author goodjava@qq.com * @date 2023/4/20 23:01 */ +@Slf4j public class CodeUtils { + private static final int CODE_STATISTICS_SOURCE_IDEA = 1; + public static String format(String code) { - return code.replaceFirst("\n+", "").replaceAll("import.*\n",""); + return code.replaceFirst("\n+", "").replaceAll("import.*\n", ""); } public static String formatRemoveEnter(String code) { @@ -23,17 +40,92 @@ public static String formatRemoveEnter1(String code) { } public static List getImportList(String code) { - return Arrays.stream(code.split("\n|;")).filter(it->it.startsWith("import")).map(it->it.replaceAll(";|import| ","")).collect(Collectors.toList()); + return Arrays.stream(code.split("\n|;")).filter(it -> it.startsWith("import")).map(it -> it.replaceAll(";|import| ", "")).collect(Collectors.toList()); } public static List getImportList2(String code) { - return Arrays.stream(code.split("\n|;")).filter(it->it.startsWith("import")).map(it->it.replaceAll(";|import","")).collect(Collectors.toList()); + return Arrays.stream(code.split("\n|;")).filter(it -> it.startsWith("import")).map(it -> it.replaceAll(";|import", "")).collect(Collectors.toList()); } public static String getComment(String code) { - return code.replaceAll("/\\*\\*|\\*/| +\\* ","").replaceAll("

","\n"); + return code.replaceAll("/\\*\\*|\\*/| +\\* ", "").replaceAll("

", "\n"); + } + + /** + * upload statistics + */ + public static void uploadCodeGenInfo(M78CodeGenerationInfo info) { + SafeRun.run(() -> { + long now = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli(); + info.setCtime(now); + info.setUtime(now); + info.setSource(CODE_STATISTICS_SOURCE_IDEA); + info.setUsername(AthenaContext.ins().getUserName()); + info.setPluginVersion(new Version().toString()); + info.setIp(AthenaContext.ins().getLocalAddress()); + info.setSystemVersion(System.getProperty("os.name").toLowerCase()); + info.setIdeVersion(ApplicationInfo.getInstance().getBuild().asString()); + Result ok = M78Service.uploadCodeInfo(GsonUtils.gson.toJson(info)); + log.info("upload code info, status:{}", ok); + }); + } + + public static void uploadCodeGenInfo(String code, String comment, String projectName, String className) { + uploadCodeGenInfo(Action.GENERATE_CODE.getCode(), code, comment, projectName, className); + } + + public static void uploadCodeGenInfo(int actionCode, String code, String comment, Project project) { + String projectName = project == null ? "" : project.getName(); + PsiClass psiClass = CodeService.getPsiClassInRead(project); + String className = psiClass == null ? "" : psiClass.getName(); + uploadCodeGenInfo(actionCode, code, comment, projectName, className); } + public static void uploadCodeGenInfo(int actionCode, String code, String comment, String projectName, String className) { + M78CodeGenerationInfo info = new M78CodeGenerationInfo(); + info.setCodeLinesCount(CodeUtils.getLineCnt(code, false)); + info.setAnnotation(CodeUtils.checkLineStartsWithComment(comment)); + info.setProjectName(projectName); + info.setClassName(className); + info.setMethodName("GENERATED"); + info.setAction(actionCode); + uploadCodeGenInfo(info); + } + + public static void uploadCodeGenInfo(int actionCode, String projectName, String className, String methodName) { + M78CodeGenerationInfo info = new M78CodeGenerationInfo(); + info.setClassName(className); + info.setProjectName(projectName); + info.setMethodName(methodName == null ? "" : methodName); + info.setCodeLinesCount(0); + info.setAction(actionCode); + uploadCodeGenInfo(info); + } + + public static int getLineCnt(String code, boolean markDown) { + int lineCount = 1; // 如果字符串不为空至少有一行 + + for (int i = 0; i < code.length(); i++) { + if (code.charAt(i) == '\n') { + lineCount++; + } + } + if (markDown) { + return Math.max(lineCount - 2, 0); + } + return lineCount; + } + + // 帮我生成一个方法,用于判断当前行是否是//开头,如果是,则返回这行,如果不是,返回null。入参是String,返回值是String,注意判断String非空,并且在判断前要trim + public static String checkLineStartsWithComment(String line) { + if (line != null && !line.trim().isEmpty()) { + String trimmedLine = line.trim(); + if (trimmedLine.startsWith("//") || trimmedLine.startsWith("/**")) { + return trimmedLine; + } + } + return null; + } public static void main(String[] args) { String code = " /**\n" + diff --git a/athena-all/src/main/java/run/mone/ultraman/common/FunctionReqUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/FunctionReqUtils.java index 115a370d8..75f069f0e 100644 --- a/athena-all/src/main/java/run/mone/ultraman/common/FunctionReqUtils.java +++ b/athena-all/src/main/java/run/mone/ultraman/common/FunctionReqUtils.java @@ -2,8 +2,8 @@ import com.google.common.collect.Maps; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.common.ConfigUtils; -import run.mone.m78.ip.util.GitUtils; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.util.GitUtils; import run.mone.ultraman.AthenaContext; import java.util.List; diff --git a/athena-all/src/main/java/run/mone/ultraman/common/GitProjectOpener.java b/athena-all/src/main/java/run/mone/ultraman/common/GitProjectOpener.java index b1cd0507c..e8eef319f 100644 --- a/athena-all/src/main/java/run/mone/ultraman/common/GitProjectOpener.java +++ b/athena-all/src/main/java/run/mone/ultraman/common/GitProjectOpener.java @@ -10,5 +10,25 @@ public class GitProjectOpener { public static void openGitProject(String projectPath) { + // 获取本地文件系统的实例 + LocalFileSystem localFileSystem = LocalFileSystem.getInstance(); + + // 使用项目路径找到对应的 VirtualFile 实例 + VirtualFile projectDirectory = localFileSystem.refreshAndFindFileByIoFile(new File(projectPath)); + + // 检查项目目录是否存在 + if (projectDirectory == null) { + System.err.println("Project directory not found: " + projectPath); + return; + } + + Project project = ProjectUtil.openOrImport(projectDirectory.getPath(), null, true); + + // 如果项目打开成功,则 project 不为 null + if (project != null) { + System.out.println("Project opened successfully: " + project.getName()); + } else { + System.err.println("Failed to open project: " + projectPath); + } } } diff --git a/athena-all/src/main/java/run/mone/ultraman/common/GsonUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/GsonUtils.java index 276a94da4..71c94caf8 100644 --- a/athena-all/src/main/java/run/mone/ultraman/common/GsonUtils.java +++ b/athena-all/src/main/java/run/mone/ultraman/common/GsonUtils.java @@ -1,6 +1,9 @@ package run.mone.ultraman.common; import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import java.util.function.Supplier; /** * @author goodjava@qq.com @@ -10,4 +13,26 @@ public class GsonUtils { public static Gson gson = new Gson(); + + public static boolean get(JsonObject obj, String key, boolean defaultValue) { + if (obj.has(key)) { + return Boolean.valueOf(obj.get(key).getAsString()); + } + return defaultValue; + } + + public static String get(JsonObject obj, String key, String defaultValue) { + if (obj.has(key)) { + return obj.get(key).getAsString(); + } + return defaultValue; + } + + public static String get(JsonObject obj, String key, Supplier supplier) { + if (obj.has(key)) { + return obj.get(key).getAsString(); + } + return supplier.get(); + } + } diff --git a/athena-all/src/main/java/run/mone/ultraman/common/ImportCode.java b/athena-all/src/main/java/run/mone/ultraman/common/ImportCode.java index cc059a12b..dfacb84b8 100644 --- a/athena-all/src/main/java/run/mone/ultraman/common/ImportCode.java +++ b/athena-all/src/main/java/run/mone/ultraman/common/ImportCode.java @@ -2,10 +2,13 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.util.MarkdownFilter; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.util.function.Consumer; + /** * @author goodjava@qq.com *

@@ -23,6 +26,13 @@ public class ImportCode { private boolean isImport = false; + private MarkdownFilter markdownFilter = new MarkdownFilter(new Consumer() { + @Override + public void accept(String s) { + CodeService.writeCode2(project, editor, s); + } + }); + public void append(String str) { if (isImportBegin(str)) { isImport = true; @@ -33,7 +43,8 @@ public void append(String str) { } else if (isImport) { importBuilder.append(str); } else { - CodeService.writeCode2(project, editor, str); + //过滤不必要的markdown标签 + markdownFilter.accept(str); } } diff --git a/athena-all/src/main/java/run/mone/ultraman/common/SafeRun.java b/athena-all/src/main/java/run/mone/ultraman/common/SafeRun.java index d5e69d81b..a0626a4d3 100644 --- a/athena-all/src/main/java/run/mone/ultraman/common/SafeRun.java +++ b/athena-all/src/main/java/run/mone/ultraman/common/SafeRun.java @@ -1,16 +1,19 @@ package run.mone.ultraman.common; +import lombok.extern.slf4j.Slf4j; + /** * @author goodjava@qq.com * @date 2023/4/19 14:30 */ +@Slf4j public class SafeRun { public static void run(Runnable runnable) { try { runnable.run(); } catch (Throwable ex) { - ex.printStackTrace(); + log.error(ex.getMessage(), ex); } } diff --git a/athena-all/src/main/java/run/mone/ultraman/common/ScopeEnum.java b/athena-all/src/main/java/run/mone/ultraman/common/ScopeEnum.java new file mode 100644 index 000000000..c9323a567 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/ScopeEnum.java @@ -0,0 +1,22 @@ +package run.mone.ultraman.common; + +/** + * @author goodjava@qq.com + * @date 2024/6/26 08:54 + */ +public enum ScopeEnum { + + SMethod("method"), + SClass("class"), + SModule("module"), + SProject("project") + ; + + + private String name; + + ScopeEnum(String name) { + this.name = name; + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/TemplateUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/TemplateUtils.java index 62ddd7cc4..c80299251 100644 --- a/athena-all/src/main/java/run/mone/ultraman/common/TemplateUtils.java +++ b/athena-all/src/main/java/run/mone/ultraman/common/TemplateUtils.java @@ -2,6 +2,7 @@ import com.google.common.collect.Maps; import org.apache.commons.compress.utils.Lists; +import org.apache.commons.lang3.tuple.Pair; import org.beetl.core.Configuration; import org.beetl.core.Function; import org.beetl.core.GroupTemplate; @@ -23,12 +24,12 @@ public static String renderTemplate(String template, Map m) { return renderTemplate(template, m, Lists.newArrayList()); } - public static String renderTemplate(String template, Map m, List functionList) { + public static String renderTemplate(String template, Map m, List> functionList) { try { StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader(); Configuration cfg = Configuration.defaultConfiguration(); GroupTemplate gt = new GroupTemplate(resourceLoader, cfg, cfg.getClass().getClassLoader()); - functionList.forEach(it -> gt.registerFunction(it.toString(), it)); + functionList.forEach(it -> gt.registerFunction(it.getKey(), it.getValue())); Template t = gt.getTemplate(template); m.forEach((k, v) -> t.binding(k, v)); String str = t.render(); diff --git a/athena-all/src/main/java/run/mone/ultraman/common/TestRunnerUtils.java b/athena-all/src/main/java/run/mone/ultraman/common/TestRunnerUtils.java new file mode 100644 index 000000000..07ea2e94b --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/TestRunnerUtils.java @@ -0,0 +1,83 @@ +package run.mone.ultraman.common; + +import com.intellij.execution.PsiLocation; +import com.intellij.execution.RunManager; +import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.junit.JUnitConfiguration; +import com.intellij.execution.junit.JUnitConfigurationType; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.ExecutionEnvironmentBuilder; +import com.intellij.execution.runners.ProgramRunner; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiAnnotation; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import lombok.SneakyThrows; +import org.apache.commons.lang3.tuple.Pair; +import run.mone.ultraman.common.adapter.TestRunnerProcessAdapter; + +import java.util.function.Consumer; + +/** + * @author goodjava@qq.com + * @date 2024/6/29 09:03 + */ +public class TestRunnerUtils { + + /** + * 运行测试的方法 + * 从数据管理器获取数据上下文,得到相关类,获取类名 + * 尝试根据类名获取测试类并获取其方法 + * 对有测试注解的方法进行 JUnit 测试并根据结果显示相应消息框 + * 处理类未找到的异常情况 + */ + @SneakyThrows + public static void runTest(Project project, String methodName, Consumer> consumer) { + PsiClass psiClass = CodeService.getPsiClass(project); + String className = psiClass.getQualifiedName(); + + PsiMethod[] methods = psiClass.getMethods(); + + // 逐个执行测试方法 + for (PsiMethod method : methods) { + if (hasTestAnnotation(method, methodName)) { + RunnerAndConfigurationSettings runSettings = RunManager.getInstance(project).createConfiguration(className + "." + method.getName(), JUnitConfigurationType.getInstance().getConfigurationFactories()[0]); + JUnitConfiguration configuration = (JUnitConfiguration) runSettings.getConfiguration(); + + // 设置测试类和方法 + JUnitConfiguration.Data data = configuration.getPersistentData(); + data.setMainClass(psiClass); + //这个很关键,保证是值测试一个method,而不是class + data.setTestMethod(PsiLocation.fromPsiElement(method)); + data.setTestMethodName(method.getName()); + + ExecutionEnvironmentBuilder builder = ExecutionEnvironmentBuilder + .createOrNull(DefaultRunExecutor.getRunExecutorInstance(), runSettings); + + ExecutionEnvironment environment = builder.build(); + + ProgramRunner runner = ProgramRunner.getRunner(DefaultRunExecutor.EXECUTOR_ID, environment.getRunProfile()); + + //直接执行,并且捕获异常,然后问ai修复 + runner.execute(environment, descriptor -> descriptor.getProcessHandler().addProcessListener(new TestRunnerProcessAdapter(project, consumer))); + + } + } + } + + private static boolean hasTestAnnotation(PsiMethod psiMethod, String methodName) { + if (!psiMethod.getName().equals(methodName)) { + return false; + } + PsiAnnotation[] annotations = psiMethod.getModifierList().getAnnotations(); + for (PsiAnnotation annotation : annotations) { + if (annotation.getQualifiedName() != null && annotation.getQualifiedName().contains("Test")) { + return true; + } + } + return false; + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/common/adapter/TestRunnerProcessAdapter.java b/athena-all/src/main/java/run/mone/ultraman/common/adapter/TestRunnerProcessAdapter.java new file mode 100644 index 000000000..dab25c531 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/common/adapter/TestRunnerProcessAdapter.java @@ -0,0 +1,65 @@ +package run.mone.ultraman.common.adapter; + +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Key; +import com.intellij.psi.PsiMethod; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; + +/** + * @author goodjava@qq.com + * @date 2024/6/30 10:47 + */ +@Slf4j +public class TestRunnerProcessAdapter extends ProcessAdapter { + + private List list = new ArrayList<>(); + + private Project project; + + private Consumer> consumer; + + public TestRunnerProcessAdapter(Project project, Consumer> consumer) { + this.project = project; + this.consumer = consumer; + } + + @Override + public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) { + list.add(event.getText()); + + } + + @Override + public void processTerminated(@NotNull ProcessEvent event) { + if (event.getExitCode() == 0) { + log.info("Process finished successfully."); + } else { + log.info("Process finished with errors."); + //发生错误了 + String error = list.stream().filter(it -> it.startsWith("##teamcity[testFailed")).findAny().orElse(""); + //获取当前PsiMethod的方法信息 + String methodStr = ApplicationManager.getApplication().runReadAction((Computable) () -> { + PsiMethod method = CodeService.getMethod(project); + if (!Objects.isNull(method)) { + String methodCode = CodeService.getMethodAndLineNumbers(method); + return methodCode; + } + return ""; + }); + log.info("method:{} \n error:{}", methodStr, error); + consumer.accept(Pair.of(methodStr, error)); + } + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/event/EventListener.java b/athena-all/src/main/java/run/mone/ultraman/event/EventListener.java index 5fdf8c63e..df9866ead 100644 --- a/athena-all/src/main/java/run/mone/ultraman/event/EventListener.java +++ b/athena-all/src/main/java/run/mone/ultraman/event/EventListener.java @@ -1,8 +1,8 @@ package run.mone.ultraman.event; import com.google.common.eventbus.Subscribe; -import run.mone.m78.ip.bo.ClassInfo; -import run.mone.m78.ip.bo.ValueInfo; +import com.xiaomi.youpin.tesla.ip.bo.ClassInfo; +import com.xiaomi.youpin.tesla.ip.bo.ValueInfo; import lombok.Getter; import run.mone.ultraman.bo.PackageInfo; import run.mone.ultraman.bo.ParamsInfo; diff --git a/athena-all/src/main/java/run/mone/ultraman/gutter/AthenaMethodLineMarkerProvider.java b/athena-all/src/main/java/run/mone/ultraman/gutter/AthenaMethodLineMarkerProvider.java new file mode 100644 index 000000000..3bed34f79 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/gutter/AthenaMethodLineMarkerProvider.java @@ -0,0 +1,94 @@ +package run.mone.ultraman.gutter; + +import com.intellij.codeInsight.daemon.LineMarkerInfo; +import com.intellij.codeInsight.daemon.LineMarkerProvider; +import com.intellij.openapi.editor.markup.GutterIconRenderer; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.FunctionUtil; +import com.xiaomi.youpin.tesla.ip.service.PsiMethodUtils; +import com.xiaomi.youpin.tesla.ip.util.EditorUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import run.mone.ultraman.statusbar.AthenaStatusBarWidget; +import run.mone.ultraman.statusbar.PopUpReq; + +import javax.swing.*; +import java.util.Collection; +import java.util.List; + +import static run.mone.ultraman.statusbar.PopUpReq.POP_ORIGIN_LINE_MARK; + +/** + * @author HawickMason@xiaomi.com + * @date 6/26/24 2:27 PM + */ +public class AthenaMethodLineMarkerProvider implements LineMarkerProvider { + + + private final String icons = "/icons/M2.svg"; + + @Override + public @Nullable LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) { + if (element instanceof PsiMethod) { + PsiMethod method = (PsiMethod) element; + if (isMethodNotConstructor(method)) { + PsiElement firstChild = PsiMethodUtils.getFirstLeafNode(method); + Icon icon = IconLoader.getIcon(icons, getClass()); + TextRange range = method.getNameIdentifier() != null ? method.getNameIdentifier().getTextRange() : method.getModifierList().getTextRange(); + return new LineMarkerInfo<>( + firstChild, + method.getNameIdentifier() != null ? method.getNameIdentifier().getTextRange() : method.getModifierList().getTextRange(), + icon, + FunctionUtil.nullConstant(), + ((mouseEvent, pe) -> { + PsiMethod psiMethod = PsiTreeUtil.getParentOfType(pe, PsiMethod.class); + AthenaStatusBarWidget.popUp(pe.getProject(), null, mouseEvent, PopUpReq.builder().offset(range.getEndOffset()).psiMethod(psiMethod).origin(POP_ORIGIN_LINE_MARK).build()); + }), + GutterIconRenderer.Alignment.LEFT + ); + } + } + + if (element instanceof PsiComment) { + PsiComment psiComment = (PsiComment) element; + PsiElement firstChild = psiComment; + + if (isValidComment(psiComment)) { + Icon icon = IconLoader.getIcon(icons, getClass()); + return new LineMarkerInfo<>( + firstChild, + psiComment.getTextRange(), + icon, + FunctionUtil.nullConstant(), + ((mouseEvent, pc) -> { + AthenaStatusBarWidget.popUp(pc.getProject(), null, mouseEvent, PopUpReq.builder().offset(pc.getTextOffset()).psiComment((PsiComment) pc).origin(POP_ORIGIN_LINE_MARK).build()); + }), + GutterIconRenderer.Alignment.LEFT + ); + } + } + return null; + } + + private static boolean isMethodNotConstructor(PsiMethod method) { + return !method.isConstructor(); + } + + private static boolean isValidComment(PsiComment psiComment) { + return EditorUtils.isNotClassHeaderComment(psiComment) + && EditorUtils.isCommentInsideClass(psiComment) + && !EditorUtils.isCommentInsideMethod(psiComment); + } + + @Override + public void collectSlowLineMarkers(@NotNull List elements, @NotNull Collection> result) { + // No slow line markers to collect + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/http/HttpClient.java b/athena-all/src/main/java/run/mone/ultraman/http/HttpClient.java index 065659862..827b01ad4 100644 --- a/athena-all/src/main/java/run/mone/ultraman/http/HttpClient.java +++ b/athena-all/src/main/java/run/mone/ultraman/http/HttpClient.java @@ -4,8 +4,8 @@ import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import run.mone.m78.ip.common.ConfigUtils; -import run.mone.m78.ip.common.NotificationCenter; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.NotificationCenter; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import okhttp3.*; @@ -70,16 +70,19 @@ public static String callHttpServer(String url, String action, String req, boole return callHttpServer(url, action, req, notify, false); } + public static String callHttpServer(String url, String action, String req, boolean notify, boolean useToken) { + return callHttpServer(url, action, req, notify, useToken, 10); + } @SneakyThrows - public static String callHttpServer(String url, String action, String req, boolean notify, boolean useToken) { + public static String callHttpServer(String url, String action, String req, boolean notify, boolean useToken, int timeout) { log.info("call action:{}", action); Stopwatch sw = Stopwatch.createStarted(); try { OkHttpClient client = new OkHttpClient.Builder() - .connectTimeout(5, TimeUnit.SECONDS) - .readTimeout(5, TimeUnit.SECONDS) - .writeTimeout(5, TimeUnit.SECONDS) + .connectTimeout(timeout, TimeUnit.SECONDS) + .readTimeout(timeout, TimeUnit.SECONDS) + .writeTimeout(timeout, TimeUnit.SECONDS) .build(); RequestBody body = RequestBody.create(MediaType.parse("application/json"), req); Request.Builder requestBuilder = new Request.Builder(); diff --git a/athena-all/src/main/java/run/mone/ultraman/http/WsClient.java b/athena-all/src/main/java/run/mone/ultraman/http/WsClient.java new file mode 100644 index 000000000..1be8fef4b --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/http/WsClient.java @@ -0,0 +1,112 @@ +package run.mone.ultraman.http; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.xiaomi.youpin.tesla.ip.bo.AiMessage; +import com.xiaomi.youpin.tesla.ip.bo.AiMessageType; +import com.xiaomi.youpin.tesla.ip.common.Base64Utils; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import okhttp3.*; +import run.mone.ultraman.common.GsonUtils; + +import java.util.concurrent.CountDownLatch; +import java.util.function.Consumer; + +/** + * @author goodjava@qq.com + * @date 2024/5/29 18:20 + */ +@Slf4j +@Data +public class WsClient { + + private WebSocket ws; + + private String id; + + private String projectName; + + private String url = "ws://127.0.0.1/ws/bot/abc"; + + private CountDownLatch latch; + + public void init(Consumer consumer) { + OkHttpClient client = new OkHttpClient(); + String token = ConfigUtils.getConfig().getzToken(); + Request request = new Request.Builder() + .url(url) + .header("athena-token", token) + .build(); + WebSocketListener listener = new WebSocketListener() { + @Override + public void onOpen(WebSocket webSocket, Response response) { + log.info("ws open"); + } + + @Override + public void onMessage(WebSocket webSocket, String text) { + log.info("Received:{}", text); + JsonObject msg = JsonParser.parseString(text).getAsJsonObject(); + String type = GsonUtils.get(msg, "type", ""); + String messageType = GsonUtils.get(msg, "messageType", ""); + + //发生错误了 + if (messageType.equals("BOT_STREAM_FAILURE")) { + String message = GsonUtils.get(msg, "message", ""); + consumer.accept(AiMessage.builder().projectName(projectName).text(message).type(AiMessageType.failure).id(id).build()); + if (null != latch) { + latch.countDown(); + } + return; + } + + if (messageType.equals("BOT_STREAM_BEGIN")) { + consumer.accept(AiMessage.builder().projectName(projectName).text("").type(AiMessageType.begin).id(id).build()); + return; + } + + if (messageType.equals("BOT_STREAM_RESULT")) { + consumer.accept(AiMessage.builder().projectName(projectName).text("").type(AiMessageType.success).id(id).build()); + webSocket.close(1000, null); + if (null != latch) { + latch.countDown(); + } + return; + } + + String message = GsonUtils.get(msg, "message", ""); + + if (messageType.equals("BOT_STREAM_EVENT")) { + //解决中文乱码的问题 + message = Base64Utils.decodeBase64String(message); + log.info("message:{}", message); + consumer.accept(AiMessage.builder().projectName(projectName).code(false).text(message).type(AiMessageType.process).id(id).build()); + } + + } + + @Override + public void onClosing(WebSocket webSocket, int code, String reason) { + webSocket.close(1000, null); + log.info("Closing: " + code + " / " + reason); + } + + @Override + public void onFailure(WebSocket webSocket, Throwable t, Response response) { + log.error("Error: " + t.getMessage()); + } + }; + ws = client.newWebSocket(request, listener); + log.info("init finish"); + } + + + //发送消息 + public void send(JsonObject req) { + ws.send(req.toString()); + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/http/handler/BaseHandler.java b/athena-all/src/main/java/run/mone/ultraman/http/handler/BaseHandler.java new file mode 100644 index 000000000..0a6d58e55 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/http/handler/BaseHandler.java @@ -0,0 +1,29 @@ +package run.mone.ultraman.http.handler; + +import com.google.gson.JsonObject; +import com.intellij.openapi.project.Project; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.common.GsonUtils; + +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author goodjava@qq.com + * @date 2024/4/28 15:45 + */ +public class BaseHandler { + + public static String getProjectName(JsonObject obj) { + String projectName = GsonUtils.get(obj, "projectName", () -> { + ConcurrentHashMap map = AthenaContext.ins().getProjectMap(); + if (map.size() >= 1) { + return new ArrayList<>(map.values()).get(0).getName(); + } + return ""; + }); + return projectName; + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/http/handler/ReadCodeHandler.java b/athena-all/src/main/java/run/mone/ultraman/http/handler/ReadCodeHandler.java new file mode 100644 index 000000000..3073df826 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/http/handler/ReadCodeHandler.java @@ -0,0 +1,156 @@ +package run.mone.ultraman.http.handler; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.PsiMethodUtils; +import com.xiaomi.youpin.tesla.ip.service.QuickFixInvokeUtil; +import com.xiaomi.youpin.tesla.ip.util.ProjectUtils; +import com.xiaomi.youpin.tesla.ip.util.PsiClassUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.mutable.MutableObject; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import run.mone.ultraman.bo.AthenaClassInfo; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.service.AthenaCodeService; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2024/4/28 15:43 + */ +@Slf4j +public class ReadCodeHandler extends BaseHandler { + + + public JsonObject execute(JsonObject obj, JsonObject resObj) { + + log.info("req:{}", obj); + + String projectName = getProjectName(obj); + String packageName = GsonUtils.get(obj, "packageName", () -> ""); + + JsonElement clsJson = obj.get("className"); + JsonElement clsListJson = obj.get("classList"); + + //获取当前打开的类 + boolean openClass = obj.has("openClass"); + + if (StringUtils.isBlank(projectName)) { + return resObj; + } + + Project project = ProjectUtils.projectFromManager(projectName); + + //读取当前打开的class + if (openClass) { + return getJsonObjectWithErrors(resObj, project); + } + + //读取指定method,并且携带行号 + if (obj.has("openMethod")) { + MutableObject mo = new MutableObject(); + ApplicationManager.getApplication().invokeAndWait(()->{ + mo.setValue(getMethodCode(obj, resObj, project)); + }); + return (JsonObject) mo.getValue(); + } + + //replaceMethod + if (obj.has("replaceMethod")) { + return replaceMethodContent(obj, resObj, project); + } + + + if (clsJson != null) { + String className = getFQCN(packageName, clsJson.getAsString()); + resObj.addProperty("data", getCode(projectName, className)); + } else if (clsListJson != null) { + JsonArray classList = clsListJson.getAsJsonArray(); +// Map codeMap = new HashMap(); + JsonArray modifiedClassArray = new JsonArray(); + for (int i = 0; i < classList.size(); i++) { + String clsName = getFQCN(packageName, classList.get(i).getAsString()); + String code = getCode(projectName, clsName); + if (StringUtils.isNotBlank(code)) { + AthenaClassInfo info = AthenaCodeService.classInfo(code); + modifiedClassArray.add(GsonUtils.gson.toJsonTree(info.getClassCode())); + } + } + resObj.add("modifiedClassArray", modifiedClassArray); + } + return resObj; + } + + @NotNull + private static JsonObject replaceMethodContent(JsonObject obj, JsonObject resObj, Project project) { + String methodCode = obj.get("methodCode").getAsString(); + String className = obj.get("className").getAsString(); + String methodName = obj.get("methodName").getAsString(); + ApplicationManager.getApplication().invokeLater(() -> { + log.info("className:{} methodName:{}", className, methodName); + PsiMethod psiMethod = CodeService.getPsiMethod(project, className, methodName); + log.info("get method:{}", psiMethod); + //替换方法内容 + PsiMethodUtils.replacePsiMethod(project, psiMethod, methodCode.trim()); + //打开要修改的类 + CodeService.openJavaClass(project, className); + }); + resObj.addProperty("data", "ok"); + return resObj; + } + + @NotNull + private static JsonObject getMethodCode(JsonObject obj, JsonObject resObj, Project project) { + String className = obj.get("className").getAsString(); + String methodName = obj.get("methodName").getAsString(); + String methodCode = CodeService.getPsiMethodByName(project, className, methodName); + resObj.addProperty("methodCode", methodCode); + return resObj; + } + + @NotNull + private static JsonObject getJsonObjectWithErrors(JsonObject resObj, Project project) { + //获取这个类的错误 + MutableObject code = new MutableObject(); + PsiFile psi = CodeService.getPsiFile(project); + code.setValue(psi.getText()); + List errors = CodeService.invoke(() -> ApplicationManager.getApplication().runReadAction((Computable>) () -> QuickFixInvokeUtil.findAllErrors(project, psi).stream().map(it -> "问题:" + it.getText() + " 问题描述:" + it.getDescription()).collect(Collectors.toList()))); + resObj.addProperty("code", (String) code.getValue()); + resObj.add("error", GsonUtils.gson.toJsonTree(errors)); + return resObj; + } + + + private static String getFQCN(String packageName, String className) { + return StringUtils.joinWith(".", packageName, className); + } + + private static String getCode(String projectName, String className) { + try { + return ReadAction.compute(() -> { + // 确保我们在正确的上下文中 + if (!ApplicationManager.getApplication().isReadAccessAllowed()) { + throw new IllegalStateException("Read access is not allowed"); + } + PsiClass psiClass = PsiClassUtils.findClassByName(ProjectUtils.projectFromManager(projectName), className); + return psiClass.getText(); + }); + } catch (Throwable e) { + log.error("failed to get code for class: {}, in project:{}", className, projectName); + return ""; + } + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/http/handler/WriteCodeHandler.java b/athena-all/src/main/java/run/mone/ultraman/http/handler/WriteCodeHandler.java new file mode 100644 index 000000000..29bbbb225 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/http/handler/WriteCodeHandler.java @@ -0,0 +1,89 @@ +package run.mone.ultraman.http.handler; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.xiaomi.youpin.tesla.ip.common.Safe; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.util.ProjectUtils; +import com.xiaomi.youpin.tesla.ip.util.PsiClassUtils; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaderNames; +import io.netty.handler.codec.http.HttpResponseStatus; +import lombok.extern.slf4j.Slf4j; +import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.bo.AthenaClassInfo; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.http.HttpResponseUtils; +import run.mone.ultraman.service.AthenaCodeService; + +/** + * @author goodjava@qq.com + * @date 2024/4/28 14:53 + */ +@Slf4j +public class WriteCodeHandler extends BaseHandler{ + + public JsonObject execute(JsonObject obj, JsonObject resObj) { + log.info("write code param:\n{}\n", obj); + //如果不传projectName,则自己计算(但如果超过1个,则就去第1个) + String projectName = getProjectName(obj); + String moduleName = GsonUtils.get(obj, "moduleName", () -> ""); + boolean hasCode = obj.has("code"); + //处理单个类的替换 + if (handleCodeReplacement(hasCode, obj, projectName, resObj)) { + return resObj; + } + JsonArray codeList = obj.getAsJsonArray("codeList"); + //这个类的定义(去除public method 的实现部分) + JsonArray codeDefinitionArray = new JsonArray(); + codeList.forEach(it -> Safe.run(() -> { + String code = it.getAsJsonObject().getAsJsonPrimitive("output").getAsString(); + log.debug("create class:\n{}", code); + AthenaClassInfo info = AthenaCodeService.classInfo(code); + codeDefinitionArray.add(GsonUtils.gson.toJsonTree(info.getClassCode())); + Project project = AthenaContext.ins().getProjectMap().get(projectName); + CodeService.invoke(() -> { + WriteCommandAction.runWriteCommandAction(project, () -> { + PsiDirectory directory = PsiClassUtils.getSourceDirectoryWithModule(project, moduleName); + directory = PsiClassUtils.createPackageDirectories(directory, info.getPackagePath()); + PsiClassUtils.createClass(project, info.getName(), code, false, directory); + log.info("create class:{} success", info.getName()); + }); + return null; + }); + })); + log.info("code definition:{}", codeDefinitionArray); + resObj.add("codeDefinitionArray", codeDefinitionArray); + return resObj; + } + + + + + private boolean handleCodeReplacement(boolean hasCode, JsonObject obj, String projectName, JsonObject resObj) { + if (hasCode) { + boolean replace = GsonUtils.get(obj, "replace", false); + if (replace) { + CodeService.invoke(() -> { + String code = obj.get("code").getAsString(); + AthenaClassInfo info = AthenaCodeService.classInfo(code); + PsiClass psiClass = PsiClassUtils.findClassByName(ProjectUtils.projectFromManager(projectName), info.getClassName()); + CodeService.replaceFileContent((PsiFile) psiClass.getParent(), obj.get("code").getAsString()); + resObj.addProperty("data", "success"); + return null; + }); + return true; + } + } + return false; + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaApplicationActivationListener.java b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaApplicationActivationListener.java index 72fa8c7a9..aece65369 100644 --- a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaApplicationActivationListener.java +++ b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaApplicationActivationListener.java @@ -1,5 +1,6 @@ package run.mone.ultraman.listener; +import com.google.common.collect.Maps; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.application.ApplicationActivationListener; @@ -8,45 +9,139 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.editor.actionSystem.EditorActionManager; +import com.intellij.openapi.editor.actionSystem.TypedAction; +import com.intellij.openapi.editor.actionSystem.TypedActionHandler; import com.intellij.openapi.wm.IdeFrame; -import run.mone.m78.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.bo.Action; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import run.mone.ultraman.AthenaInspection; +import run.mone.ultraman.common.CodeUtils; +import run.mone.ultraman.common.SafeRun; +import run.mone.ultraman.listener.bo.CompletionEnum; import run.mone.ultraman.manager.InlayHintManager; +import java.util.HashMap; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import static com.xiaomi.youpin.tesla.ip.common.Const.CONF_M78_CODE_GEN_WITH_ENTER; /** * @author goodjava@qq.com * @date 2023/7/27 22:34 */ +@Slf4j public class AthenaApplicationActivationListener implements ApplicationActivationListener { + //保证只加载一次 private AtomicBoolean init = new AtomicBoolean(false); - @Override public void applicationActivated(@NotNull IdeFrame ideFrame) { if (init.compareAndSet(false, true)) { ApplicationManager.getApplication().executeOnPooledThread(() -> { - //用来捕获 editor中输入enter + + TypedAction typedAction = TypedAction.getInstance(); + TypedActionHandler originalHandler = typedAction.getHandler(); + + //处理输入的,为以后的接口做准备 + typedAction.setupHandler((editor, charTyped, dataContext) -> { + // 在这里处理你的输入字符 + if (Character.isLetterOrDigit(charTyped)) { + // 如果输入的是字母或数字,执行一些操作 + log.debug("Typed letter or digit: " + charTyped); + setActionType(editor, "letterOrDigit"); + + @Nullable AtomicInteger id = editor.getUserData(CaretHoverEditorFactoryListener.EDIT_INCR_ID_KEY); + if (null != id) { + id.incrementAndGet(); + } + + // 此时如果有inlay内容则用户输入后dispose + InlayHintManager.ins().dispose(); + /* InlayHintManager.ins().dispose(text -> { + if (StringUtils.isNotEmpty(text)) { + CodeService.deleteCode(editor); + CodeService.formatCode(editor.getProject()); + } + });*/ + // 再次触发 + handlePluginInEditor(editor); + } + // 确保调用原始处理程序,以便其他功能(如文本输入)不会被破坏 + originalHandler.execute(editor, charTyped, dataContext); + }); + EditorActionManager actionManager = EditorActionManager.getInstance(); - EditorActionHandler originalEnterHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_ENTER); + + //用来捕获 editor中输入回车 + EditorActionHandler enterHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_ENTER); actionManager.setActionHandler(IdeActions.ACTION_EDITOR_ENTER, new EditorActionHandler() { @Override protected void doExecute(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext) { - String text = InlayHintManager.ins().getHintText(); - if (StringUtils.isNotEmpty(text)) { - CodeService.insertCode(editor.getProject(), text, false); - CodeService.deleteCode(editor); - CodeService.formatCode(editor.getProject()); - InlayHintManager.ins().dispose(); - } else { - originalEnterHandler.execute(editor, caret, dataContext); + setActionType(editor, "enter"); + + enterHandler.execute(editor, caret, dataContext); + + if (!ResourceUtils.isOpen(CONF_M78_CODE_GEN_WITH_ENTER)) { + return; + } + String comment = CodeService.getPreviousLineIfComment(editor); + log.info("comment:{}", comment); +// UltramanConsole.append(editor.getProject(), "" + comment, false); + //上一行是注释,并且结尾是(class) + if (check(comment)) { + //直接调用生成代码 + PromptInfo promptInfo = Prompt.getPromptInfo(Const.GENERATE_CODE); + if (AthenaInspection.isBotUsageConfigured(promptInfo)) { + //调用bot生成代码 + HashMap params = Maps.newHashMap(); + params.put("__code", comment.trim()); + params.put("__skip_enter", "true"); + AthenaInspection.invokePrompt(editor.getProject(), promptInfo.getPromptName(), params); + } } } + + private static boolean check(String comment) { + return StringUtils.isNotEmpty(comment) && comment.trim().endsWith(")"); + } + }); + + + //用来捕获 editor中输入tab + EditorActionHandler originalTabHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_TAB); + actionManager.setActionHandler(IdeActions.ACTION_EDITOR_TAB, new EditorActionHandler() { + @Override + protected void doExecute(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext) { + originalTabHandler.execute(editor, caret, dataContext); + InlayHintManager.ins().dispose((text) -> { + if (StringUtils.isNotEmpty(text)) { + CodeService.insertCode(editor.getProject(), text, false, InlayHintManager.ins().getCaretOffsetWhenTriggered(), editor); + CompletionEnum completionType = ConfigUtils.getConfig().getCompletionMode(); + @Nullable CaretHoverPlugin plugin = editor.getUserData(CaretHoverEditorFactoryListener.PLUGIN_KEY); + if (plugin == null || CompletionEnum.MULTI_LINE == completionType) { + //移动到方法末尾 + CodeService.moveCaretToMethodEnd(editor, CodeService.getMethod(editor.getProject())); + } else { + CodeService.moveCaretToEndOfLine(editor); + } + // 代码统计 + CodeUtils.uploadCodeGenInfo(Action.INLAY.getCode(), text, "", editor.getProject()); + } + }); + } }); //用来捕获 editor中输入esc @@ -54,15 +149,53 @@ protected void doExecute(@NotNull Editor editor, @Nullable Caret caret, DataCont actionManager.setActionHandler(IdeActions.ACTION_EDITOR_ESCAPE, new EditorActionHandler() { @Override public void doExecute(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext) { - if (null != InlayHintManager.ins().getInlay()) { - CodeService.deleteCode(editor); - CodeService.formatCode(editor.getProject()); - InlayHintManager.ins().dispose(); - } - originalEscapeHandler.execute(editor, dataContext); + InlayHintManager.ins().dispose(); + /* InlayHintManager.ins().dispose(text -> { + if (StringUtils.isNotEmpty(text)) { + CodeService.deleteCode(editor); + CodeService.formatCode(editor.getProject()); + } else { + originalEscapeHandler.execute(editor, dataContext); + } + });*/ + // 再次触发 + AthenaApplicationActivationListener.handlePluginInEditor(editor); } }); + + EditorActionHandler originalBackspaceHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE); + EditorActionHandler myBackspaceHandler = new EditorActionHandler() { + @Override + protected void doExecute(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext) { + // 在这里处理删除事件 + log.debug("Backspace key pressed"); + // 调用原始处理程序以保持默认行为(保证先影响了) + originalBackspaceHandler.execute(editor, caret, dataContext); + handlePluginInEditor(editor); + + } + }; + actionManager.setActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE, myBackspaceHandler); + + }); } } + + private static void setActionType(Editor editor, String type) { + @Nullable AtomicReference actionType = editor.getUserData(CaretHoverEditorFactoryListener.EDIT_ACTION_TYPE); + if (null != actionType) { + actionType.set(type); + } + } + + public static void handlePluginInEditor(@NotNull Editor editor) { + SafeRun.run(() -> { + CaretHoverPlugin plugin = editor.getUserData(CaretHoverEditorFactoryListener.PLUGIN_KEY); + if (null != plugin) { + //处理退出的逻辑 + plugin.handleCaretPositionChangedEvent(); + } + }); + } } diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileDocumentManagerListener.java b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileDocumentManagerListener.java index d09c99423..0a8b5b6ad 100644 --- a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileDocumentManagerListener.java +++ b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileDocumentManagerListener.java @@ -8,6 +8,9 @@ /** * @author goodjava@qq.com * @date 2023/7/14 10:25 + * + * 保存document的时候,会回调回来,以后做统计用 + * */ @Slf4j public class AthenaFileDocumentManagerListener implements FileDocumentManagerListener { diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileEditorManagerListener.java b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileEditorManagerListener.java index 8d9b2fc75..77d619079 100644 --- a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileEditorManagerListener.java +++ b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaFileEditorManagerListener.java @@ -4,9 +4,9 @@ import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.fileEditor.FileEditorManagerListener; import com.intellij.openapi.vfs.VirtualFile; -import run.mone.m78.ip.bo.ValueInfo; -import run.mone.m78.ip.common.Const; -import run.mone.m78.ip.common.Safe; +import com.xiaomi.youpin.tesla.ip.bo.ValueInfo; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Safe; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; @@ -31,6 +31,7 @@ public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile f log.info(text); ValueInfo pi = new ValueInfo(); pi.setValue(text); + //自己实现了一套event时间,以后都需要且成ide自带那套 AthenaEventBus.ins().post(pi); } }); diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaProjectManagerListener.java b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaProjectManagerListener.java index 55dd879e0..8f124a684 100644 --- a/athena-all/src/main/java/run/mone/ultraman/listener/AthenaProjectManagerListener.java +++ b/athena-all/src/main/java/run/mone/ultraman/listener/AthenaProjectManagerListener.java @@ -1,13 +1,29 @@ package run.mone.ultraman.listener; +import com.intellij.execution.Executor; +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.RunContentManager; +import com.intellij.execution.ui.RunContentWithExecutorListener; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManagerListener; -import run.mone.m78.ip.bo.robot.AiMessageManager; -import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; -import run.mone.m78.ip.common.ConfigUtils; +import com.intellij.openapi.util.Key; +import com.intellij.util.messages.MessageBusConnection; +import com.xiaomi.youpin.tesla.ip.bo.robot.AiMessageManager; +import com.xiaomi.youpin.tesla.ip.bo.robot.ProjectAiMessageManager; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Safe; +import com.xiaomi.youpin.tesla.ip.util.NetUtils; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.listener.event.TaskEvent; import run.mone.ultraman.state.FsmManager; import run.mone.ultraman.state.ProjectFsmManager; @@ -22,8 +38,49 @@ public class AthenaProjectManagerListener implements ProjectManagerListener { @Override public void projectOpened(Project project) { log.info("Project reopened: " + project.getName()); + + Safe.run(() -> { + // 订阅事件 + RunContentWithExecutorListener myListener = new RunContentWithExecutorListener() { + @Override + public void contentSelected(RunContentDescriptor descriptor, Executor executor) { + + @Nullable ProcessHandler processHandler = descriptor.getProcessHandler(); + if (processHandler != null) { + // 添加 ProcessListener 来监听输出 + processHandler.addProcessListener(new ProcessAdapter() { + @Override + public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) { + // 这里可以捕获输出信息 + String text = event.getText(); + // 根据 outputType 区分 stdout 和 stderr + if (outputType == ProcessOutputTypes.STDOUT) { + System.out.println("STDOUT: " + text); + } else if (outputType == ProcessOutputTypes.STDERR) { + System.out.println("STDERR: " + text); + } + } + }); + } + + } + + @Override + public void contentRemoved(RunContentDescriptor descriptor, Executor executor) { + // 处理内容被移除的事件 + } + }; + MessageBusConnection connection = project.getMessageBus().connect(); + connection.subscribe(RunContentManager.TOPIC, myListener); + connection.subscribe(TaskEvent.TOPIC, new TaskEvent.TaskEventListenerImpl(project)); + }); + + AthenaContext.ins().getProjectMap().put(project.getName(), project); AthenaContext.ins().setGptModel(ConfigUtils.getConfig().getModel()); + AthenaContext.ins().setNoChatModel(ConfigUtils.getConfig().getNoChatModel()); + AthenaContext.ins().setLocalAddress(NetUtils.getLocalHost()); + AthenaContext.ins().setLocalPort(ResourceUtils.getAthenaConfig().get(Const.CONF_PORT)); ProjectAiMessageManager.getInstance().putMessageManager(project.getName(), new AiMessageManager()); FsmManager fsmManager = new FsmManager(); fsmManager.setProject(project.getName()); diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/CaretHoverEditorFactoryListener.java b/athena-all/src/main/java/run/mone/ultraman/listener/CaretHoverEditorFactoryListener.java new file mode 100644 index 000000000..f2e3482dd --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/CaretHoverEditorFactoryListener.java @@ -0,0 +1,55 @@ +package run.mone.ultraman.listener; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.event.EditorFactoryEvent; +import com.intellij.openapi.editor.event.EditorFactoryListener; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import org.jetbrains.annotations.NotNull; + +import java.lang.ref.Reference; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @author goodjava@qq.com + * @date 2024/5/31 14:51 + */ +public class CaretHoverEditorFactoryListener implements EditorFactoryListener { + + + public static final Key PLUGIN_KEY = new Key<>("plugin_key"); + + public static final Key EDIT_INCR_ID_KEY = new Key<>("edit_incr_id_key"); + + //用来记录操作类型的 + public static final Key> EDIT_ACTION_TYPE = new Key<>("edit_action_type"); + + @Override + public void editorCreated(@NotNull EditorFactoryEvent event) { + Editor editor = event.getEditor(); + Project project = editor.getProject(); + if (project != null) { + CaretHoverPlugin plugin = new CaretHoverPlugin(project, editor); + editor.putUserData(EDIT_INCR_ID_KEY, new AtomicInteger()); + editor.putUserData(PLUGIN_KEY, plugin); + editor.putUserData(EDIT_ACTION_TYPE, new AtomicReference<>("")); + } + } + + @Override + public void editorReleased(@NotNull EditorFactoryEvent event) { + Editor editor = event.getEditor(); + CaretHoverPlugin plugin = editor.getUserData(PLUGIN_KEY); + if (plugin != null) { + // Perform any necessary cleanup in the plugin + plugin.editorReleased(); + // Remove the plugin from the editor's user data + editor.putUserData(PLUGIN_KEY, null); + editor.putUserData(EDIT_INCR_ID_KEY, null); + editor.putUserData(EDIT_ACTION_TYPE, null); + } + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/CaretHoverPlugin.java b/athena-all/src/main/java/run/mone/ultraman/listener/CaretHoverPlugin.java new file mode 100644 index 000000000..533402224 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/CaretHoverPlugin.java @@ -0,0 +1,475 @@ +package run.mone.ultraman.listener; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ParseResult; +import com.github.javaparser.ast.stmt.Statement; +import com.google.gson.JsonObject; +import com.intellij.codeInsight.completion.CompletionProcess; +import com.intellij.codeInsight.completion.CompletionService; +import com.intellij.codeInsight.lookup.Lookup; +import com.intellij.codeInsight.lookup.LookupEx; +import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.*; +import com.intellij.openapi.editor.event.CaretEvent; +import com.intellij.openapi.editor.event.CaretListener; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.FileTypeRegistry; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.common.Safe; +import com.xiaomi.youpin.tesla.ip.service.BotService; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import net.sf.cglib.beans.BeanCopier; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import run.mone.ultraman.common.ScopeEnum; +import run.mone.ultraman.listener.bo.CompletionEnum; +import run.mone.ultraman.manager.InlayHintManager; + +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author goodjava@qq.com + * @date 2024/5/31 14:52 + */ +@Slf4j +@Data +public class CaretHoverPlugin { + + private Project project; + + private Editor editor; + + private ReentrantLock lock = new ReentrantLock(); + + private ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor(); + + private Future future; + + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + private final BeanCopier PROMPT_COPIER = BeanCopier.create(PromptInfo.class, PromptInfo.class, false); + + /** + * 检查方法 + * 如果指定资源未打开则返回真 + * 如果事件不为空,获取旧位置,返回旧位置行和列是否都为 0 + */ + private static boolean isResourceClosedOrInitialPosition(CaretEvent event) { + //只留下了chat + if (ResourceUtils.checkDisableCodeCompletionStatus()) { + return true; + } + + if (!ResourceUtils.isOpen(Const.INLAY) || CompletionEnum.NONE == ConfigUtils.getConfig().getCompletionMode()) { + return true; + } + + if (event != null) { + //刚进来的不做任何处理 + return event.getOldPosition().line == 0 && event.getOldPosition().column == 0; + } + return false; + } + + + public CaretHoverPlugin(Project project, Editor editor) { + this.project = project; + this.editor = editor; + editor.getCaretModel().addCaretListener(new CaretListener() { + @Override + public void caretPositionChanged(CaretEvent event) { + // config设置为关闭,则不做任何处理 + if (CompletionEnum.NONE.equals(ConfigUtils.getConfig().getCompletionMode())) { + return; + } + if (isResourceClosedOrInitialPosition(event)) { + return; + } + log.debug("caretPositionChanged :{}", event.getCaret()); + try { + lock.lock(); + if (null != future && !future.isDone()) { + future.cancel(true); + } + Pair shouldComplete = shouldComplete(editor, event.getCaret()); + if (shouldComplete.getLeft()) { + int offset = editor.getCaretModel().getOffset(); + InlayHintManager.ins().setCaretOffsetWhenTriggered(offset); + log.info("start timer at offset:{}", offset); + startTimer(editor, event.getCaret(), shouldComplete.getRight()); + } + } finally { + lock.unlock(); + } + } + }); + } + + public void handleCaretPositionChangedEvent() { + if (ResourceUtils.checkDisableCodeCompletionStatus()) return; + ApplicationManager.getApplication().invokeLater(() -> { + if (isResourceClosedOrInitialPosition(null)) { + return; + } + log.debug("handleCaretPositionChangedEvent"); + try { + lock.lock(); + if (null != future) { + log.info("cancel task"); + future.cancel(true); + } + Caret caret = getCurrentCaretClass(this.editor); + InlayHintManager.ins().dispose(); + if (!InlayHintManager.ins().hasInlay() && shouldComplete(editor, caret).getLeft()) { + log.info("start timer"); + startTimer(editor, caret, ConfigUtils.getConfig().getCompletionMode()); + } + } finally { + lock.unlock(); + } + }); + } + + @NotNull + private static String getCurrentLine(Editor editor, Caret caret) { + try { + Document document = editor.getDocument(); + int lineNumber = caret.getLogicalPosition().line; + int lineStartOffset = document.getLineStartOffset(lineNumber); + int lineEndOffset = document.getLineEndOffset(lineNumber); + String lineText = document.getText().substring(lineStartOffset, lineEndOffset).trim(); + return lineText; + } catch (Throwable throwable) { + log.error(throwable.getMessage(), throwable); + return ""; + } + } + + + public static boolean isCompleteStatement(String lineText) { + JavaParser parser = new JavaParser(); + ParseResult result = parser.parseStatement(lineText); + return result.isSuccessful(); + } + + + private void startTimer(Editor editor, Caret caret, CompletionEnum completionMode) { + int delay = Integer.parseInt(ResourceUtils.getAthenaConfig().getOrDefault(Const.INLAY_DELAY, "200")); + log.info("Inlay delay time:{} ms", delay); + Safe.run(() -> this.future = pool.schedule(() -> Safe.run(() -> showInlay(editor, caret, completionMode)), delay, TimeUnit.MILLISECONDS)); + } + + + /** + * 判断是否应该完成代码自动补全。 + * 如果光标不在方法内,返回false。 + * 如果当前行为空或光标在方法内,返回true。 + */ + private Pair shouldComplete(Editor editor, Caret caret) { + if (InlayHintManager.ins().hasInlay()) { + return Pair.of(false, CompletionEnum.NONE); + } + // lookup的时候不触发 + boolean memberCompletion = isMemberCompletion2(editor); + log.debug("isMember :{}", memberCompletion); + if (memberCompletion) { + return Pair.of(false, CompletionEnum.NONE); + } + + // 不在文本编辑区时不触发 + // 非java文件不触发 + AtomicReference psiFile = new AtomicReference<>(); + WriteCommandAction.runWriteCommandAction(project, () -> { + psiFile.set(PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument())); + }); + FileType javaFileType = FileTypeRegistry.getInstance().getFileTypeByExtension("java"); + if (psiFile.get() == null || psiFile.get().getFileType() != javaFileType) { + return Pair.of(false, CompletionEnum.NONE); + } + ApplicationManager.getApplication().invokeLater(() -> { + WriteCommandAction.runWriteCommandAction(project, () -> { + Document document = editor.getDocument(); + PsiDocumentManager.getInstance(project).commitDocument(document); + }); + }); + log.debug("caret:{}", caret); + PsiMethod method = getMethod(editor, psiFile.get()); + if (null != method) { + @NotNull String line = getCurrentLine(editor, caret); + if (StringUtils.isEmpty(line)) { + //上一个操作不是回车,则忽略生成(review代码的时候经常这样) + if ("enter".equals(editor.getUserData(CaretHoverEditorFactoryListener.EDIT_ACTION_TYPE).get())) { + editor.getUserData(CaretHoverEditorFactoryListener.EDIT_ACTION_TYPE).set(null); + } else { + return Pair.of(false, CompletionEnum.NONE); + } + String bodyCode = getMethodBodyWithoutBracesNewlinesAndComments(method); + if (StringUtils.isEmpty(bodyCode)) { + // 当前行是空,并且当前方法体是空,就走多行逻辑 + return Pair.of(true, CompletionEnum.MULTI_LINE); + } + } + + if (singleLineShouldComplete(line, editor)) { + // 当前行不为空、不完整且光标在末尾的情况下才触发补全 + return Pair.of(true, CompletionEnum.SINGLE_LINE); + } + } + return Pair.of(false, CompletionEnum.NONE); + } + + private boolean isCurrentlyInLookup(Project project) { + log.info("begin isCurrentlyInLookup"); + LookupManager lookupManager = LookupManager.getInstance(project); + log.info("lookupManager:{}", lookupManager); + if (lookupManager == null) { + return false; + } + LookupEx activeLookup = lookupManager.getActiveLookup(); + if (activeLookup != null && activeLookup.getCurrentItem() != null) { + log.info("lookup:{}", activeLookup); + boolean memberCompletion = isMemberCompletion(); + log.info("isMemberCompletion:{}", memberCompletion); + return memberCompletion; + } else { + log.info("activeLookup status:{}", activeLookup); + return false; + } + } + + public boolean isMemberCompletion2(Editor editor) { + try { + int offset = editor.getCaretModel().getOffset(); + CharSequence documentText = editor.getDocument().getCharsSequence(); + return documentText.charAt(offset - 1) == '.'; + } catch (Throwable e) { + log.warn("check doc range err:", e.getMessage()); + return false; + } + } + + private static boolean isActiveLookupOrCompletionProcessPresent(Editor editor) { + log.info("in . "); + // Check if there's an active lookup + Project project = editor.getProject(); + if (project != null) { + Lookup activeLookup = LookupManager.getInstance(project).getActiveLookup(); + log.info("activelookup:{}", activeLookup); + if (activeLookup != null) { + return true; + } + } + + // Check if there's an active completion process + CompletionService completionService = CompletionService.getCompletionService(); + CompletionProcess completionProcess = completionService.getCurrentCompletion(); + log.info("completionProcess:{}", completionProcess); + return completionProcess != null; + } + + private boolean isMemberCompletion() { + log.info("in isMemberCompletion"); + CompletionService completionService = CompletionService.getCompletionService(); + CompletionProcess completionProcess = completionService.getCurrentCompletion(); + return completionProcess != null; + } + + /** + * 获取去掉大括号、换行符和单行注释的 PsiMethod body + * + * @param psiMethod 要处理的 PsiMethod + * @return 去掉大括号、换行符和单行注释的 body 字符串 + */ + public static String getMethodBodyWithoutBracesNewlinesAndComments(PsiMethod psiMethod) { + PsiCodeBlock body = psiMethod.getBody(); + if (body == null) { + return null; + } + + // 获取 body 的所有子元素 + PsiElement[] children = body.getChildren(); + StringBuilder bodyContent = new StringBuilder(); + + for (PsiElement child : children) { + String text = child.getText(); + // 跳过大括号、换行符和注释 + if (!(child instanceof PsiComment) && !text.equals("{") && !text.equals("}") && !text.trim().isEmpty()) { + bodyContent.append(text); + } + } + + return bodyContent.toString().trim(); + } + + + //从Editor中获取当前caret(class) + private Caret getCurrentCaretClass(Editor editor) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> editor.getCaretModel().getCurrentCaret()); + } + + + private PsiMethod getMethod(Editor editor, PsiFile psiFile) { + return ApplicationManager.getApplication().runReadAction((Computable) () -> { + CaretModel caretModel = editor.getCaretModel(); + int offset = caretModel.getOffset(); + PsiElement elementAtCaret = psiFile.findElementAt(offset); + PsiMethod method = PsiTreeUtil.getParentOfType(elementAtCaret, PsiMethod.class); + return method; + }); + } + + + private void showInlay(Editor editor, Caret caret, CompletionEnum completionMode) { + int id = editor.getUserData(CaretHoverEditorFactoryListener.EDIT_INCR_ID_KEY).incrementAndGet(); + + JsonObject req = new JsonObject(); + + PromptInfo promptInfo = Prompt.getPromptInfo("code_completion"); + PromptInfo forkedPromptInfo = new PromptInfo(); + PROMPT_COPIER.copy(promptInfo, forkedPromptInfo, null); + GenerateCodeReq generateCodeReq = GenerateCodeReq.builder().project(editor.getProject()).promptInfo(forkedPromptInfo).build(); + PromptService.setReq(generateCodeReq); + //生成单行代码 + if (CompletionEnum.SINGLE_LINE == completionMode) { + // 生成部分代码 (160004) 测试用的100302 + req.addProperty("botId", ResourceUtils.getAthenaConfig().getOrDefault(Const.INLAY_BOT_ID, "160004")); + if (MapUtils.isNotEmpty(forkedPromptInfo.getLabels())) { + forkedPromptInfo.getLabels().remove("analysis_scope"); + } + generateCodeReq.setUserSettingScope(ResourceUtils.getAthenaConfig().getOrDefault(Const.INLAY_SCOPE, ScopeEnum.SMethod.name())); + } else { + //生成全部代码 + //100294(比较单一的) 100317(支持上下文) + req.addProperty("botId", "100317"); + } + @NotNull JsonObject params = BotService.generateParams(generateCodeReq, generateCodeReq.getClassCodeWithMark()); + req.add("params", params); + req.addProperty("input", ""); + + //直接调用m78的bot接口,所以不走stream(open-apis/ai-plugin-new/feature/router/probot/query) + String text = callBotAndGetResult(req); + // TODO mason + log.info("mode:{}, showInlay text:{}", completionMode.getName(), text); + if (StringUtils.isEmpty(text)) { + return; + } + + //又有了新的补全 + if (id < editor.getUserData(CaretHoverEditorFactoryListener.EDIT_INCR_ID_KEY).get()) { + log.info("id:{} cancel", id); + return; + } + + + //关闭代码提示 + invokeCloseCompletion(editor); + + ApplicationManager.getApplication().invokeLater(() -> { + InlayModel inlayModel = editor.getInlayModel(); + int offset = caret.getOffset(); + int lineNumber = editor.getDocument().getLineNumber(offset); + int lineStartOffset = editor.getDocument().getLineStartOffset(lineNumber); + String lineText = editor.getDocument().getText(new TextRange(lineStartOffset, offset)); + String replace = lineText.replace("\t", " "); // 如果有\t转为四个空格,否则有问题 + String indent = replace.replaceAll("\\S", ""); // 获取当前行的缩进 + + //插入空行,为了看起来更美观 + //insertBlankLinesFromRenderer(editor, renderer); + long count = Stream.of(text.split("\n")).count(); + + @Nullable Inlay inlay = null; + if (count <= 1) { + InlayCustomRenderer renderer = new InlayCustomRenderer(text, null); + inlay = inlayModel.addInlineElement(offset, true, renderer); + } else { + InlayCustomRenderer renderer = new InlayCustomRenderer(text, indent); + inlay = inlayModel.addBlockElement(offset, true, false, 0, renderer); + } + InlayHintManager.ins().setInlay(inlay, text); /* @Nullable Inlay inlay = inlayModel.addInlineElement(offset, renderer); + InlayHintManager.ins().setInlay(inlay, text);*/ + }); + + } + + + private static void invokeCloseCompletion(Editor editor) { + if (editor == null || editor.getProject() == null || editor.getProject().isDisposed()) { + return; + } + ApplicationManager.getApplication().invokeLater(() -> CodeService.closeCompletion(editor.getProject())); + } + + private String callBotAndGetResult(JsonObject req) { + String text = ""; + try { + text = BotService.callBot(this.project, req); + } catch (Throwable ignore) { + + } + return text; + } + + private static void insertBlankLinesFromRenderer(Editor editor, InlayCustomRenderer renderer) { + //减去当前空行 + int lineSize = renderer.getLines().size() - 1; + if (lineSize > 0) { + CodeService.insertBlankLinesAtCaret(editor.getProject(), editor, lineSize); + } + } + + private boolean singleLineShouldComplete(String line, Editor editor) { + return StringUtils.isBlank(line) || notBlankLineShouldComplete(line, editor); + } + + private boolean notBlankLineShouldComplete(String line, Editor editor) { + return !CodeService.isCursorInComment(editor) + && !CodeService.isAtMultiCommentEnd(line) + && CodeService.hasValidCharCnt(line) + && !CodeService.isCaretLineOnlyAnnotation(editor) + && CodeService.isCaretAtEndOfLine(editor) + && !CodeService.isPreCharBrace(editor) + && !isCompleteStatement(line); + } + + /** + * 关闭存留的悬浮面板及相关任务 + */ + public void editorReleased() { + try { + lock.lock(); + if (future != null && !future.isDone()) { + future.cancel(true); + } + InlayHintManager.ins().dispose(); + invokeCloseCompletion(editor); + } finally { + lock.unlock(); + } + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/InlayCustomRenderer.java b/athena-all/src/main/java/run/mone/ultraman/listener/InlayCustomRenderer.java new file mode 100644 index 000000000..e0b9f83ea --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/InlayCustomRenderer.java @@ -0,0 +1,117 @@ +package run.mone.ultraman.listener; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorCustomElementRenderer; +import com.intellij.openapi.editor.Inlay; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.colors.EditorFontType; +import com.intellij.openapi.editor.impl.FontInfo; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.ui.JBColor; +import com.intellij.util.ui.UIUtil; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * @author goodjava@qq.com + * @date 2024/5/31 14:57 + */ +public class InlayCustomRenderer implements EditorCustomElementRenderer { + + + private final String text; + + @Getter + private final List lines; + + private final String indent; + + public InlayCustomRenderer(String text, String indent) { + this.text = text; + this.lines = Stream.of(text.split("\n")).collect(Collectors.toList()); + this.indent = indent; + } + + @Override + public int calcWidthInPixels(@NotNull Inlay inlay) { + FontMetrics metrics = inlay.getEditor().getContentComponent().getFontMetrics(inlay.getEditor().getColorsScheme().getFont(EditorFontType.PLAIN)); + int maxWidth = 0; + for (String line : text.split("\n")) { + int width = 0; + if (StringUtils.isNotEmpty(indent)) { + width = metrics.stringWidth(line + indent); + } else { + width = metrics.stringWidth(line); + } + if (width > maxWidth) { + maxWidth = width; + } + } + return maxWidth; + //return Math.max(getWidth(inlay.getEditor(), text), 1); + + /* FontMetrics fontMetrics = inlay.getEditor().getContentComponent().getFontMetrics(inlay.getEditor().getColorsScheme().getFont(EditorFontType.PLAIN)); + // 计算一个字符的宽度 + int charWidth = fontMetrics.charWidth('m'); // 假设使用 'm' 字符来计算平均字符宽度 + return lines.stream().mapToInt(line -> fontMetrics.stringWidth(line) + charWidth).max().orElse(0);*/ + } + + @Override + public int calcHeightInPixels(@NotNull Inlay inlay) { + FontMetrics metrics = inlay.getEditor().getContentComponent().getFontMetrics(inlay.getEditor().getColorsScheme().getFont(EditorFontType.PLAIN)); + return metrics.getHeight() * text.split("\n").length; + } + + @Override + public void paint(@NotNull Inlay inlay, @NotNull Graphics g, @NotNull Rectangle targetRegion, @NotNull TextAttributes textAttributes) { + //EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); + //Color backgroundColor = scheme.getDefaultBackground(); + // 设置自定义元素的背景颜色 + //g.setColor(backgroundColor); + //g.clearRect(targetRegion.x, targetRegion.y, targetRegion.width, targetRegion.height); + // 绘制提示内容时修改为灰色 + g.setColor(JBColor.gray); + Font font = inlay.getEditor().getColorsScheme().getFont(EditorFontType.PLAIN); + g.setFont(font); + FontMetrics fontMetrics = inlay.getEditor().getContentComponent().getFontMetrics(font); + Editor editor = inlay.getEditor(); + int y = 0; + int lineHeight = 0; + if (StringUtils.isNotEmpty(indent)) { + lineHeight = fontMetrics.getHeight(); + y = targetRegion.y + fontMetrics.getAscent(); + } else { + float lineSpacing = editor.getColorsScheme().getLineSpacing(); + lineHeight = (int) (Math.ceil(fontMetrics.getHeight() * lineSpacing)); + y = targetRegion.y + editor.getAscent(); + } + // 绘制多行文本并应用缩进 + for (String line : text.split("\n")) { + if (StringUtils.isNotEmpty(indent)) { + g.drawString(indent + line, targetRegion.x, y); + } else { + g.drawString(line, targetRegion.x, y); + } + y += lineHeight; + } + /*// 获取编辑器的行间距 + Editor editor = inlay.getEditor(); + float lineSpacing = editor.getColorsScheme().getLineSpacing(); + + // Draw each line, adjusting the y position for each line + int lineHeight = (int) (Math.ceil(fontMetrics.getHeight() * lineSpacing)); + int y = targetRegion.y + editor.getAscent(); + for (String line : lines) { + g.drawString(indent + line, targetRegion.x, y); + y += lineHeight; + }*/ + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/bo/CompletionEnum.java b/athena-all/src/main/java/run/mone/ultraman/listener/bo/CompletionEnum.java new file mode 100644 index 000000000..7dae00eee --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/bo/CompletionEnum.java @@ -0,0 +1,74 @@ +package run.mone.ultraman.listener.bo; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author HawickMason@xiaomi.com + * @date 6/4/24 10:00 AM + */ +public enum CompletionEnum { + + NONE(-1, "disable_line_completion", "关闭", true), + + OPEN(2, "open", "开启", true), + + SINGLE_LINE(0, "single_line_completion", "单行(方法内实时触发)", false), + + MULTI_LINE(1, "multi_line_completion", "多行(空方法内触发)", false); + + private final int code; + private final String name; + + private final String desc; + + private final boolean display; + + private static final Map valMap = Arrays.stream(values()).collect(Collectors.toMap(CompletionEnum::getCode, Function.identity())); + + private static final Map nameMap = Arrays.stream(values()).collect(Collectors.toMap(CompletionEnum::getName, Function.identity())); + + private static final Map descMap = Arrays.stream(values()).collect(Collectors.toMap(CompletionEnum::getDesc, Function.identity())); + + CompletionEnum(int code, String name, String desc, boolean display) { + this.code = code; + this.name = name; + this.desc = desc; + this.display = display; + } + + public int getCode() { + return code; + } + + public String getName() { + return name; + } + + public String getDesc() { + return desc; + } + + public boolean isDisplay() { + return display; + } + + public static CompletionEnum getTypeEnumByCode(int code) { + return valMap.getOrDefault(code, NONE); + } + + public static CompletionEnum getTypeEnumByName(String name) { + return nameMap.getOrDefault(name, NONE); + } + + public static CompletionEnum getTypeEnumByDesc(String desc) { + return descMap.getOrDefault(desc, NONE); + } + + public static List getDisplayList() { + return Arrays.stream(values()).filter(CompletionEnum::isDisplay).map(CompletionEnum::getDesc).collect(Collectors.toList()); + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/listener/event/TaskEvent.java b/athena-all/src/main/java/run/mone/ultraman/listener/event/TaskEvent.java new file mode 100644 index 000000000..7e5665934 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/listener/event/TaskEvent.java @@ -0,0 +1,57 @@ +package run.mone.ultraman.listener.event; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; +import com.intellij.util.messages.Topic; +import lombok.Builder; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import run.mone.ultraman.background.AiBackgroundTask; + +/** + * @author goodjava@qq.com + * @date 2024/6/1 21:48 + */ +@Data +@Builder +@Slf4j +public class TaskEvent { + + public static final Topic TOPIC = Topic.create("TaskEvent", TaskEventListener.class); + + private String message; + + private long time; + + + public interface TaskEventListener { + void onEvent(TaskEvent event); + } + + public static class TaskEventListenerImpl implements TaskEventListener { + + private Project project; + + private AiBackgroundTask task; + + public TaskEventListenerImpl(Project project) { + this.project = project; + } + + @Override + public void onEvent(TaskEvent event) { + if (event.getMessage().equals("begin")) { + this.task = new AiBackgroundTask(project, "Athena"); + ProgressManager.getInstance().run(task); + } + if (event.getMessage().equals("end")) { + if (null != this.task) { + this.task.cancel(); + log.info("use time:{} s", event.getTime()); + } + } + } + } + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/manager/AthenaTypedActionHandler.java b/athena-all/src/main/java/run/mone/ultraman/manager/AthenaTypedActionHandler.java index 499acf12b..0b5d666e1 100644 --- a/athena-all/src/main/java/run/mone/ultraman/manager/AthenaTypedActionHandler.java +++ b/athena-all/src/main/java/run/mone/ultraman/manager/AthenaTypedActionHandler.java @@ -19,5 +19,23 @@ public class AthenaTypedActionHandler extends TypedHandlerDelegate { return super.charTyped(c, project, editor, file); } + // @Override +// public void execute(@NotNull Editor editor, char c, @NotNull DataContext dataContext) { +// if (c == '\u001B') { // ESC 键 +// // 处理取消操作 +//// Inlay inlay = InlayHintManager.addInlayHint(editor,"abc"); // 获取你的 Inlay 对象 +//// inlay.dispose(); // 移除 Inlay +// System.out.println("-->Esc"); +// } else if (c == '\n') { // ENTER 键 +// // 处理确认操作 +//// String hintText = ; // 获取你的预输入内容 +//// int offset = editor.getCaretModel().getOffset(); // 获取当前的插入点位置 +//// editor.getDocument().insertString(offset, hintText); // 插入预输入内容 +// System.out.println("-->Enter"); +// } else { +// // 如果按下的不是 ESC 或 ENTER 键,就按照默认的行为处理 +// originalHandler.execute(editor, c, dataContext); +// } +// } } diff --git a/athena-all/src/main/java/run/mone/ultraman/manager/InlayHintManager.java b/athena-all/src/main/java/run/mone/ultraman/manager/InlayHintManager.java index b1dfa8dd3..8afe8d401 100644 --- a/athena-all/src/main/java/run/mone/ultraman/manager/InlayHintManager.java +++ b/athena-all/src/main/java/run/mone/ultraman/manager/InlayHintManager.java @@ -3,21 +3,52 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.Inlay; import com.intellij.openapi.editor.InlayModel; -import lombok.Getter; +import org.apache.commons.lang3.StringUtils; import run.mone.ultraman.render.AthenaInlayRenderer; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; + /** * @author goodjava@qq.com * @date 2023/7/21 14:07 */ public class InlayHintManager { - @Getter private Inlay inlay; - @Getter private String hintText; + private AtomicInteger caretOffsetWhenTriggered = new AtomicInteger(); + + + public synchronized Inlay getInlay() { + return inlay; + } + + + public synchronized void setInlay(Inlay inlay, String hintText) { + this.inlay = inlay; + this.hintText = hintText; + } + + public void removeBlockInlay() { + if (inlay != null) { + inlay.dispose(); + } + } + + public synchronized boolean hasInlay() { + return null != this.inlay; + } + + public int getCaretOffsetWhenTriggered() { + return caretOffsetWhenTriggered.get(); + } + + public void setCaretOffsetWhenTriggered(int offset) { + this.caretOffsetWhenTriggered.set(offset); + } private static final class LazyHolder { private static final InlayHintManager ins = new InlayHintManager(); @@ -27,14 +58,31 @@ public static final InlayHintManager ins() { return LazyHolder.ins; } - public void dispose() { + public synchronized void dispose() { if (null != inlay) { inlay.dispose(); + inlay = null; this.hintText = null; } } + public synchronized void dispose(Consumer consumer) { + if (null != inlay) { + if (StringUtils.isEmpty(this.hintText)) { + this.hintText = "null"; + } + consumer.accept(this.hintText); + inlay.dispose(); + inlay = null; + this.hintText = null; + } else { + consumer.accept(""); + } + } + + + public Inlay addInlayHint(Editor editor, int offset, String hintText) { InlayModel inlayModel = editor.getInlayModel(); this.hintText = hintText; diff --git a/athena-all/src/main/java/run/mone/ultraman/quickfix/M78Inspection.java b/athena-all/src/main/java/run/mone/ultraman/quickfix/M78Inspection.java new file mode 100644 index 000000000..f0694ae0b --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/quickfix/M78Inspection.java @@ -0,0 +1,54 @@ +package run.mone.ultraman.quickfix; + +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.psi.JavaElementVisitor; +import com.intellij.psi.PsiElementVisitor; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + * @date 2024/4/21 11:58 + */ +public class M78Inspection extends LocalInspectionTool { + + + @Override + public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + return new MyVisitor(holder); + } + + + private static class MyVisitor extends JavaElementVisitor { + + private String packageStr = ""; + + private String className = ""; + + private final ProblemsHolder holder; + + public MyVisitor(ProblemsHolder holder) { + this.holder = holder; + } + + } + + + + @Override + public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getDisplayName() { + return "MyInspection"; + } + + @Override + public @NonNls @NotNull String getShortName() { + return "MyInspection"; + } + + @Override + public @Nls(capitalization = Nls.Capitalization.Sentence) @NotNull String getGroupDisplayName() { + return "MyInspection"; + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/quickfix/MethoNameLocalQuickFix.java b/athena-all/src/main/java/run/mone/ultraman/quickfix/MethoNameLocalQuickFix.java new file mode 100644 index 000000000..67a6763c7 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/quickfix/MethoNameLocalQuickFix.java @@ -0,0 +1,32 @@ +package run.mone.ultraman.quickfix; + +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.util.IntentionFamilyName; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiIdentifier; +import com.intellij.psi.PsiMethod; +import org.jetbrains.annotations.NotNull; + +/** + * @author goodjava@qq.com + * @date 2024/4/21 12:41 + */ +public class MethoNameLocalQuickFix implements LocalQuickFix { + @Override + public @IntentionFamilyName @NotNull String getFamilyName() { + return "Method Name Inspection"; + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + PsiElement element = descriptor.getPsiElement(); + if (element instanceof PsiIdentifier) { + PsiMethod method = (PsiMethod)element.getParent(); + String methodName = method.getName(); + String newMethodName = methodName.replaceAll("\\d", ""); + method.setName(newMethodName); + } + } +} diff --git a/athena-all/src/main/java/run/mone/ultraman/render/AthenaInlayRenderer.java b/athena-all/src/main/java/run/mone/ultraman/render/AthenaInlayRenderer.java index 7ff97b6c3..d1e7626ce 100644 --- a/athena-all/src/main/java/run/mone/ultraman/render/AthenaInlayRenderer.java +++ b/athena-all/src/main/java/run/mone/ultraman/render/AthenaInlayRenderer.java @@ -7,7 +7,9 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.colors.EditorFontType; import com.intellij.openapi.editor.ex.util.EditorUtil; +import com.intellij.openapi.editor.impl.EditorImpl; import com.intellij.openapi.editor.markup.TextAttributes; +import com.xiaomi.youpin.tesla.ip.service.CodeService; import org.jetbrains.annotations.NotNull; import java.awt.*; @@ -25,6 +27,7 @@ public class AthenaInlayRenderer implements EditorCustomElementRenderer { public AthenaInlayRenderer(String hintText, Editor editor) { this.hintText = hintText; this.editor = editor; + } @Override diff --git a/athena-all/src/main/java/run/mone/ultraman/service/AgentService.java b/athena-all/src/main/java/run/mone/ultraman/service/AgentService.java new file mode 100644 index 000000000..9ecd030e0 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/service/AgentService.java @@ -0,0 +1,30 @@ +package run.mone.ultraman.service; + +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; + +/** + * @author goodjava@qq.com + * @date 2024/2/27 14:31 + */ +public class AgentService { + + + /** + * 关闭项目中所有打开的文件。 + * + * @param project 当前操作的项目对象 + */ + public static void closeAllOpenFilesInProject(Project project) { + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + // 获取所有打开的文件 + VirtualFile[] openFiles = fileEditorManager.getOpenFiles(); + // 循环关闭每一个打开的文件 + for (VirtualFile openFile : openFiles) { + fileEditorManager.closeFile(openFile); + } + } + + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/service/AiCodeService.java b/athena-all/src/main/java/run/mone/ultraman/service/AiCodeService.java index a6d1d9024..92947cb95 100644 --- a/athena-all/src/main/java/run/mone/ultraman/service/AiCodeService.java +++ b/athena-all/src/main/java/run/mone/ultraman/service/AiCodeService.java @@ -1,25 +1,37 @@ package run.mone.ultraman.service; +import com.google.gson.JsonObject; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.common.ConfigUtils; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.service.PromptService; +import lombok.extern.slf4j.Slf4j; +import run.mone.ultraman.bo.DesensitizeReq; +import run.mone.ultraman.common.GsonUtils; +import run.mone.ultraman.http.HttpClient; /** * @author goodjava@qq.com * @date 2023/12/10 15:28 */ +@Slf4j public class AiCodeService { public static void generateBizCode(String scope, Project project, String comment) { ApplicationManager.getApplication().invokeLater(() -> PromptService.dynamicInvoke(getGenerateCodeReq(project, scope, comment))); } + //计算两数和(method) + + + public static GenerateCodeReq getGenerateCodeReq(Project project, String scope, String comment) { - PromptInfo promptInfo = Prompt.getPromptInfo("biz_sidecar"); + PromptInfo promptInfo = Prompt.getPromptInfo(Const.GENERATE_CODE); return GenerateCodeReq.builder() .scope(scope) .chatComment(comment) @@ -31,5 +43,24 @@ public static GenerateCodeReq getGenerateCodeReq(Project project, String scope, .build(); } + /** + * Desensitizes a given Java code snippet by sending it to a configured AI proxy service and returns the desensitized version if the service responds with success; otherwise, returns the original snippet. + */ + public static String desensitizeCode(String codeSnippet) { + try { + String url = ConfigUtils.getConfig().getAiProxy() + "/desensitize"; + DesensitizeReq req = DesensitizeReq.builder().text(codeSnippet).langType("java").aiDesensitizeFlag(false).zzToken(ConfigUtils.getConfig().getzToken()).build(); + String rst = HttpClient.post(url, GsonUtils.gson.toJson(req)); + JsonObject res = GsonUtils.gson.fromJson(rst, JsonObject.class); + int code = res.get("code").getAsInt(); + if (code == 0) { + return res.get("data").getAsString(); + } + return codeSnippet; + } catch (Throwable ex) { + log.error(ex.getMessage()); + return codeSnippet; + } + } } diff --git a/athena-all/src/main/java/run/mone/ultraman/service/AthenaCodeService.java b/athena-all/src/main/java/run/mone/ultraman/service/AthenaCodeService.java index 74ba3d2f9..a157f156a 100644 --- a/athena-all/src/main/java/run/mone/ultraman/service/AthenaCodeService.java +++ b/athena-all/src/main/java/run/mone/ultraman/service/AthenaCodeService.java @@ -3,19 +3,24 @@ import com.github.javaparser.JavaParser; import com.github.javaparser.ParseResult; import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.ImportDeclaration; +import com.github.javaparser.ast.Node; +import com.github.javaparser.ast.PackageDeclaration; import com.github.javaparser.ast.body.*; import com.github.javaparser.ast.comments.Comment; +import com.github.javaparser.ast.expr.AnnotationExpr; +import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPrivateModifier; import com.google.common.hash.Hashing; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.bo.AiMessage; -import run.mone.m78.ip.bo.MessageConsumer; -import run.mone.m78.ip.bo.z.EmbeddingStatus; -import run.mone.m78.ip.bo.z.ZKnowledgeRes; -import run.mone.m78.ip.bo.z.ZResult; -import run.mone.m78.ip.common.NotificationCenter; -import run.mone.m78.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.bo.AiMessage; +import com.xiaomi.youpin.tesla.ip.bo.MessageConsumer; +import com.xiaomi.youpin.tesla.ip.bo.z.EmbeddingStatus; +import com.xiaomi.youpin.tesla.ip.bo.z.ZKnowledgeRes; +import com.xiaomi.youpin.tesla.ip.bo.z.ZResult; +import com.xiaomi.youpin.tesla.ip.common.NotificationCenter; +import com.xiaomi.youpin.tesla.ip.service.CodeService; import it.unimi.dsi.fastutil.Pair; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -53,32 +58,151 @@ public static String getCodeServer() { @SneakyThrows public static Pair callProxy(Project project, Map map, String promptName, int timeout) { - return null; + CountDownLatch latch = new CountDownLatch(1); + StringBuilder sb = new StringBuilder(); + CodeService.generateCodeWithAi4(project, promptName, new String[]{}, map, (p, msg) -> { + }, new MessageConsumer() { + @Override + public void onEvent(AiMessage message) { + sb.append(message.getText()); + } + + @Override + public void end(AiMessage message) { + latch.countDown(); + } + }); + latch.await(timeout, TimeUnit.SECONDS); + String str = sb.toString(); + return Pair.of(str.length(), str); } //解析代码,返回一个列表,每个元素包含一个类信息和对应的代码字符串 public static List> parseCode(String code) { - return null; + JavaParser javaParser = new JavaParser(); + CompilationUnit cu = javaParser.parse(code).getResult().get(); + List> res = new ArrayList<>(); + cu.findAll(ClassOrInterfaceDeclaration.class).stream().forEach(c -> { + String classCode = c.toString(); + String md5 = md5(classCode); + + AthenaClassInfo ci = AthenaClassInfo.builder().name(c.getNameAsString()).md5(md5).classCode(classCode).build(); + res.add(AthenaPair.of(ci, classCode)); + }); + return res; } - public static AthenaClassInfo classInfo(String code) { - return null; + public static AthenaClassInfo classInfoWithDetail(String code, boolean needDetail) { + int len = code.length(); + + JavaParser javaParser = new JavaParser(); + ParseResult pr = javaParser.parse(code); + if (!pr.isSuccessful()) { + System.out.println(pr.getProblems()); + return null; + } + CompilationUnit cu = pr.getResult().get(); + Optional classOptional = cu.findAll(ClassOrInterfaceDeclaration.class).stream().findFirst(); + + String packagePath = ""; + + // 获取包声明 + Optional packageDeclaration = cu.getPackageDeclaration(); + if (packageDeclaration.isPresent()) { + // 获取包的完整路径 + packagePath = packageDeclaration.get().getNameAsString(); + } + + //只保留public method的函数定义 + List methodList = cu.findAll(MethodDeclaration.class).stream().filter(it -> it.isPublic()).map(it -> { + if (it.getBody().isPresent()) { + it.remove(it.getBody().get()); + } + return it.toString(); + }).collect(Collectors.toList()); + + + //干掉所有private的函数 + cu.findAll(MethodDeclaration.class).stream().filter(NodeWithPrivateModifier::isPrivate).forEach(Node::removeForced); + + //干掉构造函数 + cu.findAll(ConstructorDeclaration.class).stream().forEach(Node::removeForced); + + cu.findAll(InitializerDeclaration.class, InitializerDeclaration::isStatic).forEach(Node::removeForced); + + if (len > 5000) { + //删除所有字段 + cu.findAll(FieldDeclaration.class).stream().forEach(Node::removeForced); + } + + String name = classOptional.isPresent() ? classOptional.get().getNameAsString() : ""; + + List list = new ArrayList<>(); + List annoList = new ArrayList<>(); + if (classOptional.isPresent()) { + annoList = classOptional.get().getAnnotations().stream().map(AnnotationExpr::getNameAsString).collect(Collectors.toList()); + list = classOptional.get().getImplementedTypes().stream().map(Node::toString).collect(Collectors.toList()); + } + + AthenaClassInfo athenaClassInfo = AthenaClassInfo.builder().name(name).packagePath(packagePath).interfaceList(list).annoList(annoList).publicMethodList(methodList).classCode(cu.toString()).build(); + + if (needDetail) { + List imports = cu.getImports().stream().map(ImportDeclaration::getNameAsString).collect(Collectors.toList()); + athenaClassInfo.setImports(imports); + } + + return athenaClassInfo; } + public static AthenaClassInfo classInfo(String code) { + return classInfoWithDetail(code, false); + } public static String parseAndSkipCode(String code) { + JavaParser javaParser = new JavaParser(); + CompilationUnit cu = javaParser.parse(code).getResult().get(); + List list = cu.findAll(MethodDeclaration.class).stream().filter(it -> { + Optional comment = it.getComment(); + if (comment.isPresent()) { + comment.stream().filter(it2 -> { + if (it2.isLineComment() && it2.toString().startsWith("//skip")) { + return false; + } + return true; + }); + } + return true; + }).collect(Collectors.toList()); return ""; } //解析方法代码,返回一个包含AthenaMethodInfo对象的列表 public static List parseMethodCode(String code) { - return null; + JavaParser javaParser = new JavaParser(); + CompilationUnit cu = javaParser.parse(code).getResult().get(); + return cu.findAll(MethodDeclaration.class).stream().map(it -> { + String methodCode = it.toString(); + return AthenaMethodInfo.builder() + .name(it.getNameAsString()) + .md5(md5(methodCode)) + .code(methodCode).build(); + }) + .collect(Collectors.toList()); } //解析方法代码,返回一个包含AthenaMethodInfo对象的列表 public static List parseFieldCode(String code) { - return null; + JavaParser javaParser = new JavaParser(); + CompilationUnit cu = javaParser.parse(code).getResult().get(); + return cu.findAll(FieldDeclaration.class).stream().map(it -> { + String fieldCode = it.toString(); + return AthenaFieldInfo.builder() + .name(fieldCode) + .md5(md5(fieldCode)) + .code(fieldCode).build(); + }) + .collect(Collectors.toList()); } @@ -89,31 +213,73 @@ public static String md5(String code) { //上传方法代码的实现 public static void uploadMethodCode(CodeReq req) { + if (!openCodeServer) { + return; + } + List list = parseMethodCode(req.getCode()); + req.setData(gson.toJson(list)); + HttpClient.asyncCallHttpServer(getCodeServer() + "/upload/method", "upload_method_code", gson.toJson(req), (msg) -> NotificationCenter.notice(null, "biz code upload success", true)); } //获取方法代码列表 public static List getMethodCodeList(CodeReq req) { - return null; + if (!openCodeServer) { + return Lists.newArrayList(); + } + String res = HttpClient.callHttpServer(getCodeServer() + "/code/method", "get_method_code", req.getRequirement()); + Type typeOfT = new TypeToken>() { + }.getType(); + return gson.fromJson(res, typeOfT); } public static EmbeddingStatus embeddingStatus(CodeReq req) { - return null; + String res = HttpClient.callHttpServer(getCodeServer() + "/api/z/open/athena/code/embedding/status", "embedding_status", gson.toJson(req)); + Type typeOfT = new TypeToken>() { + }.getType(); + ZResult zres = gson.fromJson(res, typeOfT); + return zres.getData(); } //上传代码到服务器(那边的服务器会计算向量) public static void uploadCode(CodeReq req) { + if (!openCodeServer) { + return; + } + List> list = parseCode(req.getCode()).stream().collect(Collectors.toList()); + req.setData(gson.toJson(list)); + HttpClient.asyncCallHttpServer(getCodeServer() + "/api/z/open/athena/code/embedding", "upload_code", gson.toJson(req), (msg) -> NotificationCenter.notice(null, "biz code upload success", true)); } //获取和这次业务相关的代码(根据需求取回相应的代码片段) public static List getCodeList(CodeReq req) { + if (!openCodeServer) { + return Lists.newArrayList(); + } + log.info("project name:{} module name:{}", req.getProjectName(), req.getModuleName()); + try { + String res = HttpClient.callHttpServer(getCodeServer() + "/api/z/open/athena/code/similarQuery", "get_code", gson.toJson(req)); + Type typeOfT = new TypeToken>>() { + }.getType(); + ZResult> result = gson.fromJson(res, typeOfT); + return result.getData(); + } catch (Throwable ex) { + log.error(ex.getMessage(), ex); + } return Lists.newArrayList(); } public static List callSimilar(CodeReq req) { - return null; + if (!openCodeServer) { + return Lists.newArrayList(); + } + String res = HttpClient.callHttpServer(getCodeServer() + "/api/z/open/athena/code/similarQuery3", "get_code", gson.toJson(req)); + Type typeOfT = new TypeToken>>() { + }.getType(); + ZResult> result = gson.fromJson(res, typeOfT); + return result.getData(); } diff --git a/athena-all/src/main/java/run/mone/ultraman/service/AutoFlushBizService.java b/athena-all/src/main/java/run/mone/ultraman/service/AutoFlushBizService.java index e5288ae6c..8c1aa6c73 100644 --- a/athena-all/src/main/java/run/mone/ultraman/service/AutoFlushBizService.java +++ b/athena-all/src/main/java/run/mone/ultraman/service/AutoFlushBizService.java @@ -5,11 +5,13 @@ import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; -import run.mone.m78.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; import lombok.extern.slf4j.Slf4j; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; /** * @author wmin @@ -23,10 +25,47 @@ public class AutoFlushBizService { static String CHANGED = "changed"; public static void notifyDocumentChanged(VirtualFile file){ + + if (null == file) { + return; + } + + try { + if (LabelUtils.getLabelValue(null, "auto_biz_write", "false").equals("true") && file.getFileType() == JavaFileType.INSTANCE) { + String filePath = file.getPath(); + if (fileChangeStatus.containsKey(filePath)){ + Stack oldStack = fileChangeStatus.get(filePath); + if (null==oldStack || oldStack.empty()){ + Stack stack = new Stack<>(); + stack.push(CHANGED); + fileChangeStatus.put(filePath, stack); + } + } else { + Stack stack = new Stack<>(); + stack.push(CHANGED); + fileChangeStatus.put(filePath, stack); + } + } + } catch (Exception e){ + log.error("notifyDocumentChanged error."+file.getPath(), e); + } } public static void notifyDocumentClosed(VirtualFile file, Project project){ - + try { + if (LabelUtils.getLabelValue(null, "auto_biz_write", "false").equals("true") && file.getFileType() == JavaFileType.INSTANCE) { + String filePath = file.getPath(); + if (fileChangeStatus.containsKey(filePath)){ + Stack oldStack = fileChangeStatus.get(filePath); + if (null!=oldStack && !oldStack.empty() && CHANGED.equals(oldStack.pop())){ + log.info("file closed after changed, filePath:{}", filePath); + autoFlushBiz(file, project); + } + } + } + } catch (Exception e){ + log.error("notifyDocumentClosed error."+file.getPath(), e); + } } public static void autoFlushBiz(VirtualFile file, Project project){ @@ -34,4 +73,13 @@ public static void autoFlushBiz(VirtualFile file, Project project){ ModuleService.uploadFileText(project, module, file); } +// public void init(){ +// Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> { +// if (LabelUtils.getLabelValue(null, "auto_biz_write", "false").equals("true")){ +// fileChangeStatus.entrySet().forEach(i ->{ +// +// }); +// } +// }, 5, 10, TimeUnit.MINUTES); +// } } diff --git a/athena-all/src/main/java/run/mone/ultraman/service/ModuleService.java b/athena-all/src/main/java/run/mone/ultraman/service/ModuleService.java index be46af1be..38bd1756e 100644 --- a/athena-all/src/main/java/run/mone/ultraman/service/ModuleService.java +++ b/athena-all/src/main/java/run/mone/ultraman/service/ModuleService.java @@ -16,11 +16,11 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiJavaFile; import com.intellij.psi.PsiManager; -import run.mone.m78.ip.common.Const; -import run.mone.m78.ip.common.NotificationCenter; -import run.mone.m78.ip.service.TextService; -import run.mone.m78.ip.util.LabelUtils; -import run.mone.m78.ip.util.PsiClassUtils; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.NotificationCenter; +import com.xiaomi.youpin.tesla.ip.service.TextService; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.util.PsiClassUtils; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; import run.mone.ultraman.background.AthenaTask; @@ -39,13 +39,18 @@ public class ModuleService { /** * 上传单个java file 到 code server - * * @param project * @param module * @param file */ public static void uploadFileText(Project project, Module module, VirtualFile file) { - + Task.Backgroundable task = new Task.Backgroundable(project, "Upload code to code server.") { + @Override + public void run(@NotNull ProgressIndicator indicator) { + ApplicationManager.getApplication().invokeLater(() -> sendToCodeServer(Lists.newArrayList(javaFileText(project, module, file)), project, module, "virtual file")); + } + }; + AthenaTask.start(task); } @@ -56,21 +61,80 @@ public static void uploadFileText(Project project, Module module, VirtualFile fi * @param module */ public static void uploadModelText(Project project, Module module) { - + Task.Backgroundable task = new Task.Backgroundable(project, "Upload code to code server.") { + @Override + public void run(@NotNull ProgressIndicator indicator) { + ApplicationManager.getApplication().invokeLater(() -> { + List list = new ArrayList<>(); + ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots(); + for (VirtualFile contentRoot : contentRoots) { + projectFileIndex.iterateContentUnderDirectory(contentRoot, virtualFile -> { + if (virtualFile.getFileType() == JavaFileType.INSTANCE) { + String str = javaFileText(project, module, virtualFile); + list.add(str); + } + return true; + }); + } + sendToCodeServer(list, project, module, "module"); + }); + + } + }; + AthenaTask.start(task); } private static void sendToCodeServer(List list, Project project, Module module, String type) { + String str = Joiner.on("\n\n").join(list); + + //上传到code 服务器 + new Thread(() -> { + log.info("upload code {} type:{}", list.size(), type); + AthenaCodeService.uploadCode(CodeReq.builder().projectName(project.getName()) + .moduleName(module.getName()) + .code(str) + .build()); + }).start(); + + + NotificationCenter.notice(project, "biz code size:" + str.length() + " module name:" + module.getName() + " type:" + type, true); + //一次性写入 + if (LabelUtils.getLabelValue(null, "biz_write", "false").equals("true")) { + TextService.writeContent(project, Const.MODULE_FILE_NAME, module.getName(), () -> { + }, "```\n" + str + "\n```"); + } } public static String javaFileText(Project project, Module module, VirtualFile virtualFile) { - return ""; + PsiManager psiManager = PsiManager.getInstance(project); + PsiFile psiFile = psiManager.findFile(virtualFile); + + List list = new ArrayList<>(); + if (psiFile instanceof PsiJavaFile) { + PsiJavaFile psiJavaFile = (PsiJavaFile) psiFile; + //跳过测试类 + if (psiJavaFile.getName().endsWith("Test.java")) { + return ""; + } + PsiClass[] psiClasses = psiJavaFile.getClasses(); + for (PsiClass psiClass : psiClasses) { + //跳过接口 + if (psiClass.isInterface()) { + continue; + } + list.add(classText(project, psiClass)); + } + } + return Joiner.on("\n\n").join(list); } public static String classText(Project project, PsiClass psiClass) { - return ""; + String text = PsiClassUtils.getInterfaceText(project, psiClass); + return text; } } diff --git a/athena-all/src/main/java/run/mone/ultraman/startup/AthenaStartupActivity.java b/athena-all/src/main/java/run/mone/ultraman/startup/AthenaStartupActivity.java new file mode 100644 index 000000000..bed4d57d9 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/startup/AthenaStartupActivity.java @@ -0,0 +1,32 @@ +//package run.mone.ultraman.startup; +// +//import com.intellij.openapi.project.Project; +//import com.intellij.openapi.startup.ProjectActivity; +//import kotlin.Unit; +//import kotlin.coroutines.Continuation; +//import lombok.extern.slf4j.Slf4j; +//import org.jetbrains.annotations.NotNull; +//import org.jetbrains.annotations.Nullable; +// +///** +// * @author goodjava@qq.com +// * @date 2024/5/29 09:20 +// */ +//@Slf4j +//public class AthenaStartupActivity implements ProjectActivity { +// +// @Nullable +// @Override +// public Object execute(@NotNull Project project, @NotNull Continuation continuation) { +// log.info("open project:{}", project.getName()); +//// TerminalExecutionConsole terminalConsole = new TerminalExecutionConsole(project, new JBTerminalWidget(project)); +//// terminalConsole.getTerminalWidget().addMessageFilter(new Filter() { +//// @Override +//// public @Nullable Result applyFilter(@NotNull String line, int entireLength) { +//// return null; +//// } +//// }); +// +// return null; +// } +//} diff --git a/athena-all/src/main/java/run/mone/ultraman/state/AthenaEvent.java b/athena-all/src/main/java/run/mone/ultraman/state/AthenaEvent.java index d2c118ee6..e8b38b304 100644 --- a/athena-all/src/main/java/run/mone/ultraman/state/AthenaEvent.java +++ b/athena-all/src/main/java/run/mone/ultraman/state/AthenaEvent.java @@ -1,7 +1,7 @@ package run.mone.ultraman.state; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.common.PromptType; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/ultraman/state/CalState.java b/athena-all/src/main/java/run/mone/ultraman/state/CalState.java index 1fa8c3735..0438b473d 100644 --- a/athena-all/src/main/java/run/mone/ultraman/state/CalState.java +++ b/athena-all/src/main/java/run/mone/ultraman/state/CalState.java @@ -1,6 +1,6 @@ package run.mone.ultraman.state; -import run.mone.m78.ip.common.ChromeUtils; +import com.xiaomi.youpin.tesla.ip.common.ChromeUtils; /** * @author goodjava@qq.com diff --git a/athena-all/src/main/java/run/mone/ultraman/state/FsmManager.java b/athena-all/src/main/java/run/mone/ultraman/state/FsmManager.java index 020ce5acb..264ae0f8a 100644 --- a/athena-all/src/main/java/run/mone/ultraman/state/FsmManager.java +++ b/athena-all/src/main/java/run/mone/ultraman/state/FsmManager.java @@ -1,6 +1,6 @@ package run.mone.ultraman.state; -import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; +import com.xiaomi.youpin.tesla.ip.bo.robot.ProjectAiMessageManager; import lombok.Getter; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; diff --git a/athena-all/src/main/java/run/mone/ultraman/state/GlobalState.java b/athena-all/src/main/java/run/mone/ultraman/state/GlobalState.java index d746440a3..a8931ad94 100644 --- a/athena-all/src/main/java/run/mone/ultraman/state/GlobalState.java +++ b/athena-all/src/main/java/run/mone/ultraman/state/GlobalState.java @@ -1,6 +1,6 @@ package run.mone.ultraman.state; -import run.mone.m78.ip.util.UltramanConsole; +import com.xiaomi.youpin.tesla.ip.util.UltramanConsole; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import run.mone.ultraman.common.GsonUtils; @@ -28,8 +28,8 @@ public class GlobalState extends AthenaState { @Override public void execute(StateReq req, StateContext context) { //10秒一打印 - if (System.currentTimeMillis() - lastUpdateTime > 10000) { - log.info("project:{} state:{}", context.getProject(), this.fsm.getCurrentState()); + if (System.currentTimeMillis() - lastUpdateTime > 100000) { + log.debug("project:{} state:{}", context.getProject(), this.fsm.getCurrentState()); if (StringUtils.isNotEmpty(context.getProject())) { UltramanConsole.append(context.getProject(), "ai fsm state:" + this.fsm.getCurrentState() + " step:(" + context.getStep() + "/" + context.getFinishStep() + ") question:" + context.getQuestion() + "(" + context.getPromptStep() + "/" + context.getFinishPromptStep() + ")"); } diff --git a/athena-all/src/main/java/run/mone/ultraman/state/InitQuestionState.java b/athena-all/src/main/java/run/mone/ultraman/state/InitQuestionState.java index 9d0ce48d9..881d9569f 100644 --- a/athena-all/src/main/java/run/mone/ultraman/state/InitQuestionState.java +++ b/athena-all/src/main/java/run/mone/ultraman/state/InitQuestionState.java @@ -1,7 +1,7 @@ package run.mone.ultraman.state; import com.google.common.base.Splitter; -import run.mone.m78.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; import org.apache.commons.lang3.StringUtils; import run.mone.ultraman.common.GsonUtils; diff --git a/athena-all/src/main/java/run/mone/ultraman/state/PromptAndFunctionProcessor.java b/athena-all/src/main/java/run/mone/ultraman/state/PromptAndFunctionProcessor.java index cd665f745..1fc201c0f 100644 --- a/athena-all/src/main/java/run/mone/ultraman/state/PromptAndFunctionProcessor.java +++ b/athena-all/src/main/java/run/mone/ultraman/state/PromptAndFunctionProcessor.java @@ -3,22 +3,24 @@ import com.google.common.base.Stopwatch; import com.google.gson.JsonObject; import com.intellij.openapi.project.Project; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.PromptContext; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.bo.chatgpt.Completions; -import run.mone.m78.ip.bo.chatgpt.Format; -import run.mone.m78.ip.bo.chatgpt.Message; -import run.mone.m78.ip.bo.robot.*; -import run.mone.m78.ip.common.ChromeUtils; -import run.mone.m78.ip.common.Const; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.service.AiService; -import run.mone.m78.ip.service.PromptService; -import run.mone.m78.ip.service.RobotService; -import run.mone.m78.ip.util.ResourceUtils; -import run.mone.m78.ip.util.UltramanConsole; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.PromptContext; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.Completions; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.Format; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.Message; +import com.xiaomi.youpin.tesla.ip.bo.robot.*; +import com.xiaomi.youpin.tesla.ip.common.ChromeUtils; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.service.AiService; +import com.xiaomi.youpin.tesla.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.service.RobotService; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.util.ResourceUtils; +import com.xiaomi.youpin.tesla.ip.util.UltramanConsole; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import run.mone.ultraman.AthenaContext; import run.mone.ultraman.common.FunctionReqUtils; @@ -32,6 +34,8 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import static com.xiaomi.youpin.tesla.ip.common.Const.USE_BOT_MODEL; + /** * @author goodjava@qq.com * @date 2023/12/4 17:53 @@ -71,7 +75,15 @@ public static JsonObject callPrompt(Project project, PromptInfo promptInfo, Map< Completions completions = Completions.builder().stream(false).response_format(Format.builder().build()).messages(messageList).build(); UltramanConsole.append(project, "call ai prompt:" + promptInfo.getPromptName()); Stopwatch swCallAi = Stopwatch.createStarted(); - JsonObject jsonObj = AiService.call(GsonUtils.gson.toJson(completions), Long.parseLong(promptInfo.getLabels().getOrDefault("timeout", "50000")), vip); + + boolean jsonResult = promptInfo.open("json_result", "true"); + //如果是local,使用自己定义的模型 + if (LabelUtils.open(Const.OPEN_AI_TEST)) { + completions.setModel(ResourceUtils.getAthenaConfig().getOrDefault(Const.OPEN_AI_MODEL, "gpt4_o")); + } else { + completions.setModel(StringUtils.isNotBlank(AthenaContext.ins().getNoChatModel()) || !USE_BOT_MODEL.equals(AthenaContext.ins().getNoChatModel()) ? AthenaContext.ins().getNoChatModel() : "gpt4_o"); + } + JsonObject jsonObj = AiService.call(GsonUtils.gson.toJson(completions), Long.parseLong(promptInfo.getLabels().getOrDefault("timeout", "50000")), vip, jsonResult); UltramanConsole.append(project, "call ai prompt:" + promptInfo.getPromptName() + " finish res:" + jsonObj + " use time:" + swCallAi.elapsed(TimeUnit.SECONDS) + "s"); return jsonObj; } diff --git a/athena-all/src/main/java/run/mone/ultraman/state/QuestionState.java b/athena-all/src/main/java/run/mone/ultraman/state/QuestionState.java index df48464ee..fa299f3b7 100644 --- a/athena-all/src/main/java/run/mone/ultraman/state/QuestionState.java +++ b/athena-all/src/main/java/run/mone/ultraman/state/QuestionState.java @@ -1,10 +1,10 @@ package run.mone.ultraman.state; -import run.mone.m78.ip.bo.robot.AiChatMessage; -import run.mone.m78.ip.bo.robot.MessageType; -import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; -import run.mone.m78.ip.bo.robot.Role; -import run.mone.m78.ip.common.ChromeUtils; +import com.xiaomi.youpin.tesla.ip.bo.robot.AiChatMessage; +import com.xiaomi.youpin.tesla.ip.bo.robot.MessageType; +import com.xiaomi.youpin.tesla.ip.bo.robot.ProjectAiMessageManager; +import com.xiaomi.youpin.tesla.ip.bo.robot.Role; +import com.xiaomi.youpin.tesla.ip.common.ChromeUtils; import lombok.extern.slf4j.Slf4j; /** diff --git a/athena-all/src/main/java/run/mone/ultraman/state/StateReq.java b/athena-all/src/main/java/run/mone/ultraman/state/StateReq.java index c1e4b9e3e..4d7c0a332 100644 --- a/athena-all/src/main/java/run/mone/ultraman/state/StateReq.java +++ b/athena-all/src/main/java/run/mone/ultraman/state/StateReq.java @@ -1,7 +1,7 @@ package run.mone.ultraman.state; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.common.PromptType; import lombok.Builder; import lombok.Data; diff --git a/athena-all/src/main/java/run/mone/ultraman/state/WaitQuestionState.java b/athena-all/src/main/java/run/mone/ultraman/state/WaitQuestionState.java index 5f32daa83..d1d5f802a 100644 --- a/athena-all/src/main/java/run/mone/ultraman/state/WaitQuestionState.java +++ b/athena-all/src/main/java/run/mone/ultraman/state/WaitQuestionState.java @@ -1,9 +1,9 @@ package run.mone.ultraman.state; import com.google.gson.reflect.TypeToken; -import run.mone.m78.ip.bo.robot.AiChatMessage; -import run.mone.m78.ip.bo.robot.ProjectAiMessageManager; -import run.mone.m78.ip.bo.robot.Role; +import com.xiaomi.youpin.tesla.ip.bo.robot.AiChatMessage; +import com.xiaomi.youpin.tesla.ip.bo.robot.ProjectAiMessageManager; +import com.xiaomi.youpin.tesla.ip.bo.robot.Role; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; diff --git a/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidget.java b/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidget.java index d1fe65ccb..d34cb67c4 100644 --- a/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidget.java +++ b/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidget.java @@ -1,6 +1,11 @@ package run.mone.ultraman.statusbar; +import com.google.common.collect.ImmutableList; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.editor.VisualPosition; +import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; @@ -11,29 +16,42 @@ import com.intellij.openapi.wm.StatusBarWidget; import com.intellij.ui.awt.RelativePoint; import com.intellij.util.Consumer; -import run.mone.m78.ip.bo.GenerateCodeReq; -import run.mone.m78.ip.bo.PromptInfo; -import run.mone.m78.ip.common.Const; -import run.mone.m78.ip.common.Prompt; -import run.mone.m78.ip.common.PromptType; -import run.mone.m78.ip.service.PromptService; -import run.mone.m78.ip.util.LabelUtils; +import com.xiaomi.youpin.tesla.ip.bo.GenerateCodeReq; +import com.xiaomi.youpin.tesla.ip.bo.PromptInfo; +import com.xiaomi.youpin.tesla.ip.bo.Tag; +import com.xiaomi.youpin.tesla.ip.common.Const; +import com.xiaomi.youpin.tesla.ip.common.Prompt; +import com.xiaomi.youpin.tesla.ip.common.PromptType; +import com.xiaomi.youpin.tesla.ip.service.CodeService; +import com.xiaomi.youpin.tesla.ip.service.PromptService; +import com.xiaomi.youpin.tesla.ip.util.EditorUtils; +import com.xiaomi.youpin.tesla.ip.util.LabelUtils; +import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import run.mone.ultraman.AthenaContext; +import run.mone.ultraman.AthenaInspection; import run.mone.ultraman.bo.ClientData; import run.mone.ultraman.statusbar.bo.PopupItem; import java.awt.*; import java.awt.event.MouseEvent; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; +import static com.xiaomi.youpin.tesla.ip.common.Const.GENERATE_CODE; +import static com.xiaomi.youpin.tesla.ip.common.Const.UNIT_TEST; +import static run.mone.ultraman.statusbar.PopUpReq.POP_ORIGIN_LINE_MARK; +import static run.mone.ultraman.statusbar.PopUpReq.POP_ORIGIN_STATUS_BAR; + /** * @author goodjava@qq.com * @date 2023/7/18 23:41 */ +@Slf4j public class AthenaStatusBarWidget implements StatusBarWidget { private final Project project; @@ -66,48 +84,22 @@ public void dispose() { @Override public @Nullable @NlsContexts.Tooltip String getTooltipText() { - return "Athena"; + return Const.PLUGIN_NAME; } @Override public @Nullable Consumer getClickConsumer() { return (MouseEvent e) -> { - if (!LabelUtils.open(Const.ENABLE_ATHENA_STATUS_BAR)) { return; } - - List collectedList = Prompt.getCollected(); - collectedList.addAll(Prompt.getPromptInfoByTag("system")); - List list = collectedList.stream().filter(it -> it.getTags().stream().map(i -> i.getName()).collect(Collectors.toList()).contains("popup")).map(it -> PopupItem.builder().name(it.getPromptName()).desc(it.getDesc()).build()).collect(Collectors.toList()); - ListPopup listPopup = JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep("Prompt", list) { - @Override - public PopupStep onChosen(PopupItem selectedValue, boolean finalChoice) { - ApplicationManager.getApplication().invokeLater(() -> { - PromptInfo info = Prompt.getPromptInfo(selectedValue.getName()); - PromptType type = Prompt.getPromptType(info); - ClientData clientData = AthenaContext.ins().getClientData(project.getName()); - PromptService.dynamicInvoke(GenerateCodeReq.builder() - .scope(clientData.getScope()) - .project(project) - .projectName(project.getName()) - .promptInfo(info).promptType(type) - .promptName(selectedValue.getName()) - .build()); - }); - return super.onChosen(selectedValue, finalChoice); - } - }); - Rectangle r = statusBar.getComponent().getBounds(); - Point p = new Point(r.x + r.width, r.y + r.height); - RelativePoint showPoint = new RelativePoint(statusBar.getComponent(), p); - listPopup.show(showPoint); + popUp(project, statusBar, e, PopUpReq.builder().build()); }; } @Override public @NotNull @NlsContexts.Label String getText() { - return "Athena"; + return Const.PLUGIN_NAME; } @Override @@ -116,4 +108,108 @@ public float getAlignment() { } }; } + + + //弹出插件的界面 + public static void popUp(Project project, StatusBar statusBar, MouseEvent mouseEvent, PopUpReq req) { + if (!Objects.isNull(req.getPsiMethod())) { + CodeService.moveCaretToMethod(CodeService.getEditor(project), req.getPsiMethod()); + } + if (!Objects.isNull(req.getPsiComment())) { + CodeService.moveCaretToOffset(CodeService.getEditor(project), req.getOffset()); + } + + List collectedList = new ArrayList<>(); + if (POP_ORIGIN_STATUS_BAR == req.getOrigin()) { + collectedList.add(Prompt.getPromptInfo(GENERATE_CODE)); + collectedList.addAll(Prompt.getPromptInfoByTag("method_inspection")); + collectedList.addAll(Prompt.getPromptInfoByTag("status_bar")); + } else if (POP_ORIGIN_LINE_MARK == req.getOrigin()) { + if (req.getPsiComment() != null) { + collectedList.add(Prompt.getPromptInfo(GENERATE_CODE)); + } else { + collectedList.addAll(Prompt.getPromptInfoByTag("method_inspection")); + } + } + if (collectedList.isEmpty()) { + collectedList.add(PromptInfo.builder() + .tags(ImmutableList.of(Tag.builder().name("popup").build())) + .promptName("无操作") + .desc("无操作") + .build()); + } + List list = collectedList.stream() + .filter(it -> it.getTags() + .stream() + .map(Tag::getName) + .toList() + .contains("popup")) + .map(it -> PopupItem.builder().name(it.getPromptName()).desc(it.getDesc()).build()).collect(Collectors.toList()); + ListPopup listPopup = JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep<>("Mione AI Code助手", list) { + @Override + public PopupStep onChosen(PopupItem selectedValue, boolean finalChoice) { + String pName = selectedValue.getName(); + //移动光标位置 + if (GENERATE_CODE.equals(pName)) { + EditorUtils.moveCaretToCommentEnd(EditorUtils.getEditor(project)); + } + if (UNIT_TEST.equals(pName)) { + doFinalStep(() -> ApplicationManager.getApplication().runReadAction(() -> { + executePrompt(pName, project); + })); + } else { + ApplicationManager.getApplication().executeOnPooledThread(() -> { + executePrompt(pName, project); + }); + } + return super.onChosen(selectedValue, finalChoice); + } + }); + + if (mouseEvent != null) { + listPopup.showInScreenCoordinates(mouseEvent.getComponent(), mouseEvent.getLocationOnScreen()); + } else if (statusBar != null) { + Rectangle r = statusBar.getComponent().getBounds(); + Point p = new Point(r.x + r.width, r.y + r.height); + RelativePoint showPoint = new RelativePoint(statusBar.getComponent(), p); + listPopup.show(showPoint); + } else { + Editor editor = EditorUtils.getEditor(project); + if (editor instanceof EditorEx) { + EditorEx editorEx = (EditorEx) editor; + LogicalPosition logicalPosition = editorEx.getCaretModel().getLogicalPosition(); + VisualPosition visualPosition = editorEx.logicalToVisualPosition(logicalPosition); + Point point = editorEx.visualPositionToXY(visualPosition); + RelativePoint showPoint = new RelativePoint(editorEx.getContentComponent(), point); + listPopup.show(showPoint); + } + } + } + + private static void executePrompt(String promptName, Project project) { + PromptInfo promptInfo = Prompt.getPromptInfo(promptName); + PromptType promptType = Prompt.getPromptType(promptInfo); + ClientData clientData = AthenaContext.ins().getClientData(project.getName()); + if (AthenaInspection.isBotUsageConfigured(promptInfo)) { + promptType = PromptType.executeBot; + } + PromptService.dynamicInvoke(GenerateCodeReq.builder() + .scope(clientData.getScope()) + .project(project) + .projectName(project.getName()) + .promptInfo(promptInfo) + .promptType(promptType) + .promptName(promptName) + .build()); + } + + private static boolean isCursorInComment(Project project) { + Editor editor = CodeService.getEditor(project); + if (null != editor) { + boolean isInComment = CodeService.isCursorInComment(editor); + log.debug("is in comment:{}", isInComment); + return isInComment; + } + return false; + } } diff --git a/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidgetFactory.java b/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidgetFactory.java index c1a3e69a8..6e344d059 100644 --- a/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidgetFactory.java +++ b/athena-all/src/main/java/run/mone/ultraman/statusbar/AthenaStatusBarWidgetFactory.java @@ -4,6 +4,7 @@ import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.StatusBarWidget; import com.intellij.openapi.wm.StatusBarWidgetFactory; +import com.xiaomi.youpin.tesla.ip.common.Const; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -20,7 +21,7 @@ public class AthenaStatusBarWidgetFactory implements StatusBarWidgetFactory { @Override public @Nls @NotNull String getDisplayName() { - return "Athena"; + return Const.PLUGIN_NAME; } @Override diff --git a/athena-all/src/main/java/run/mone/ultraman/statusbar/PopUpReq.java b/athena-all/src/main/java/run/mone/ultraman/statusbar/PopUpReq.java new file mode 100644 index 000000000..23c41fb33 --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/statusbar/PopUpReq.java @@ -0,0 +1,38 @@ +package run.mone.ultraman.statusbar; + +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiMethod; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author goodjava@qq.com + * @date 2024/6/27 13:01 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class PopUpReq implements Serializable { + + public static final int POP_ORIGIN_STATUS_BAR = 0; + + public static final int POP_ORIGIN_LINE_MARK = 1; + + private PsiMethod psiMethod; + + private PsiComment psiComment; + + private Editor editor; + + private int offset; + + @Builder.Default + private int origin = POP_ORIGIN_STATUS_BAR; + +} diff --git a/athena-all/src/main/java/run/mone/ultraman/visitor/M78Visitor.java b/athena-all/src/main/java/run/mone/ultraman/visitor/M78Visitor.java new file mode 100644 index 000000000..4b427670b --- /dev/null +++ b/athena-all/src/main/java/run/mone/ultraman/visitor/M78Visitor.java @@ -0,0 +1,153 @@ +package run.mone.ultraman.visitor; + +import com.google.common.collect.Lists; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.psi.*; +import com.xiaomi.youpin.tesla.ip.util.ImportUtils; +import com.xiaomi.youpin.tesla.ip.util.PsiClassFixer; +import com.xiaomi.youpin.tesla.ip.util.PsiClassUtils; +import org.apache.commons.collections.CollectionUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author goodjava@qq.com + * @date 2024/4/21 21:19 + */ +public class M78Visitor extends JavaElementVisitor { + + private String packageStr = ""; + + private String className = ""; + + private PsiJavaFile javaFile; + + private List missedImports; // HINT: 如果想要添加其他的import,须在配置访问者前设置该map + + private List wildCardImportPackages; // HINT: xxx.* 导入 + + + @Override + public void visitJavaFile(@NotNull PsiJavaFile file) { + this.javaFile = file; + this.packageStr = file.getPackageName(); + + @Nullable PsiImportList importList = file.getImportList(); + if (null != importList) { + this.visitImportList(importList); + } + + PsiClass[] classes = file.getClasses(); + Arrays.stream(classes).forEach(it -> { + this.visitClass(it); + }); + + } + + @Override + public void visitPackageStatement(@NotNull PsiPackageStatement statement) { + String text = statement.getPackageName(); + System.out.println("packcage:" + text); + this.packageStr = text; + } + + //如果缺少相应的字段,则直接添加这些字段 + @Override + public void visitClass(@NotNull PsiClass psiClass) { + String className = psiClass.getQualifiedName(); + System.out.println("class:" + className); + this.className = className; + + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(psiClass.getProject()); + + Map annotationMap = Arrays.stream(psiClass.getAnnotations()).collect(Collectors.toMap(PsiAnnotation::getQualifiedName, Function.identity())); + if (!annotationMap.containsKey("lombok.Data") && !annotationMap.containsKey("Data")) { + WriteCommandAction.runWriteCommandAction(this.javaFile.getProject(), () -> { + psiClass.getModifierList().addAnnotation("Data"); + }); + } + + + //psiClass.ggetFields 转换成map key = name + Map fieldMap = Arrays.stream(psiClass.getFields()) + .collect(Collectors.toMap(PsiField::getName, Function.identity())); + + System.out.println(fieldMap); + if (!fieldMap.containsKey("id1")) { + ApplicationManager.getApplication().invokeLater(() -> { + + PsiField idField = elementFactory.createField("id1", PsiTypes.intType()); + // 将注解添加到字段上 + idField.getModifierList().addAnnotation("Id"); + PsiClassFixer.addFields(psiClass, Lists.newArrayList(idField)); + }); + } + } + + @Override + public void visitMethod(PsiMethod method) { + String methodName = method.getName(); + System.out.println("methodName:" + methodName); + } + + + //处理有没导入的类 + @Override + public void visitImportList(@NotNull PsiImportList list) { + Map map = Arrays.stream(list.getImportStatements()).collect(Collectors.toMap(PsiImportStatement::getQualifiedName, Function.identity())); + if (!map.containsKey("lombok.Data")) { + //添加进来缺失的lombok.Data + ApplicationManager.getApplication().invokeLater(() -> { + WriteCommandAction.runWriteCommandAction(this.javaFile.getProject(), () -> { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(list.getProject()); + PsiClass psiClass = ImportUtils.createPsiClass(elementFactory, "lombok.Data"); + PsiImportStatement importStatement = elementFactory.createImportStatement(psiClass); + javaFile.getImportList().add(importStatement); + if (CollectionUtils.isNotEmpty(missedImports)) { + // 添加其他确实的import + for (String missingClass : missedImports) { + PsiClass other = ImportUtils.createPsiClass(elementFactory, missingClass); + PsiImportStatement otherImport = elementFactory.createImportStatement(other); + javaFile.getImportList().add(otherImport); + } + + } + if (CollectionUtils.isNotEmpty(wildCardImportPackages)) { + // 添加 wildcard import + for (String packageName : wildCardImportPackages) { + PsiImportStatement wildCardImport = elementFactory.createImportStatementOnDemand(packageName); + javaFile.getImportList().add(wildCardImport); + } + } + }); + }); + } + + } + + + //添加注解 + @Override + public void visitField(@NotNull PsiField field) { + String name = field.getName(); + if (name.equals("id")) { + @Nullable PsiAnnotation anno = field.getAnnotation("dev.morphia.annotations.Id"); + System.out.println("field:" + anno); + } + } + + public void setMissedImports(List missedImports) { + this.missedImports = missedImports; + } + + public void setWildCardImportPackages(List wildCardImportPackages) { + this.wildCardImportPackages = wildCardImportPackages; + } +} diff --git a/athena-all/src/main/resources/META-INF/plugin.xml b/athena-all/src/main/resources/META-INF/plugin.xml index b139a0e38..f5d27ec99 100644 --- a/athena-all/src/main/resources/META-INF/plugin.xml +++ b/athena-all/src/main/resources/META-INF/plugin.xml @@ -4,13 +4,23 @@ Athena - mone - - - - + mone + + + + Mione Ai, an AI programming assistant. Produced by Mione +

    +
  • 功能入口统一至 "Suggestion":默认快捷键Alt+Enter(Windows/Linux) Opt + Enter(Mac)
  • +
  • 改进行内提示功能: 多行(空方法时触发),单行(方法内触发), 触发时间2s
  • +
  • 修复了若干已知问题
  • +
+

Version 2024.06.19.2

+ ]]> + JUnit + org.jetbrains.plugins.terminal - + - + - + + + + implementationClass="run.mone.ultraman.quickfix.M78Inspection"/> + + + + implementationClass="run.mone.ultraman.AthenaInspection"/> + + + + + + + + + + + + implementation="com.xiaomi.youpin.tesla.ip.search.AthenaSearchEverywhereContributorFactory"/> - + - + - + - + - + @@ -90,7 +117,7 @@ - run.mone.m78.ip.component.project.AthenaProjectComment + com.xiaomi.youpin.tesla.ip.component.project.AthenaProjectComment @@ -99,20 +126,16 @@ - run.mone.m78.ip.component.PluginComponent + com.xiaomi.youpin.tesla.ip.component.PluginComponent - run.mone.m78.ip.component.TeslaAppComponent + com.xiaomi.youpin.tesla.ip.component.TeslaAppComponent - run.mone.m78.ip.component.VersionComponent - - - - run.mone.m78.ip.component.UltramanComponent + com.xiaomi.youpin.tesla.ip.component.VersionComponent @@ -120,15 +143,14 @@ - - - - - - + + + + + - + diff --git a/athena-all/src/main/resources/athena.properties b/athena-all/src/main/resources/athena.properties new file mode 100644 index 000000000..58c68da71 --- /dev/null +++ b/athena-all/src/main/resources/athena.properties @@ -0,0 +1 @@ +pluginVersion = 2024.07.17.1 diff --git a/athena-all/src/main/resources/icons/M-2.svg b/athena-all/src/main/resources/icons/M-2.svg new file mode 100644 index 000000000..c1352e38c --- /dev/null +++ b/athena-all/src/main/resources/icons/M-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/athena-all/src/main/resources/icons/M.svg b/athena-all/src/main/resources/icons/M.svg new file mode 100644 index 000000000..006677108 --- /dev/null +++ b/athena-all/src/main/resources/icons/M.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/athena-all/src/main/resources/icons/M2.svg b/athena-all/src/main/resources/icons/M2.svg new file mode 100644 index 000000000..f54b7dcce --- /dev/null +++ b/athena-all/src/main/resources/icons/M2.svg @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/athena-all/src/test/java/run/mone/ultraman/test/AiTest.java b/athena-all/src/test/java/run/mone/ultraman/test/AiTest.java index bcad78290..a3ef47323 100644 --- a/athena-all/src/test/java/run/mone/ultraman/test/AiTest.java +++ b/athena-all/src/test/java/run/mone/ultraman/test/AiTest.java @@ -3,11 +3,15 @@ import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.JsonObject; -import run.mone.m78.ip.bo.chatgpt.Completions; -import run.mone.m78.ip.bo.chatgpt.Format; -import run.mone.m78.ip.bo.chatgpt.Message; -import run.mone.m78.ip.service.LocalAiService; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.Completions; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.Format; +import com.xiaomi.youpin.tesla.ip.bo.chatgpt.Message; +import com.xiaomi.youpin.tesla.ip.service.LocalAiService; +import lombok.SneakyThrows; import org.junit.Test; +import run.mone.openai.StreamListener; + +import java.util.concurrent.TimeUnit; /** * @author goodjava@qq.com @@ -23,9 +27,27 @@ public void testCall() { Completions completions = Completions.builder() .stream(false) .response_format(Format.builder().build()) - .model("gpt-4-1106-preview").messages(Lists.newArrayList(Message.builder().role("system").content("你是我的ai助手,请返回json格式数据").build(),Message.builder().role("user").content("1+1=?").build())).build(); +// .model("gpt-4-1106-preview") + .model("gpt-4o") + .messages(Lists.newArrayList(Message.builder().role("system").content("你是我的ai助手,请返回json格式数据").build(),Message.builder().role("user").content("1+1=?").build())).build(); JsonObject res = LocalAiService.call(gson.toJson(completions)); System.out.println(res); } + @SneakyThrows + @Test + public void testCall2() { + Completions completions = Completions.builder() + .stream(true) + .response_format(Format.builder().build()) +// .model("gpt-4-1106-preview") + .model("gpt-4o") + .messages(Lists.newArrayList(Message.builder().role("system").content("你是我的ai助手,请返回json格式数据").build(),Message.builder().role("user").content("1+1=?").build())).build(); + LocalAiService.completions(gson.toJson(completions), str -> { + System.out.println(str); + }); + + TimeUnit.MINUTES.sleep(1); + } + } diff --git a/athena-all/src/test/java/run/mone/ultraman/test/AthenaCodeServiceTest.java b/athena-all/src/test/java/run/mone/ultraman/test/AthenaCodeServiceTest.java index a955f065a..0050c3378 100644 --- a/athena-all/src/test/java/run/mone/ultraman/test/AthenaCodeServiceTest.java +++ b/athena-all/src/test/java/run/mone/ultraman/test/AthenaCodeServiceTest.java @@ -7,11 +7,16 @@ import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.InitializerDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.stmt.BlockStmt; +import com.github.javaparser.ast.stmt.Statement; +import com.xiaomi.youpin.tesla.ip.util.FixCodeUtils; import lombok.SneakyThrows; import org.junit.Test; import run.mone.ultraman.bo.AthenaClassInfo; import run.mone.ultraman.bo.AthenaFieldInfo; import run.mone.ultraman.bo.AthenaMethodInfo; +import run.mone.ultraman.bo.AthenaPair; +import run.mone.ultraman.listener.CaretHoverPlugin; import run.mone.ultraman.service.AthenaCodeService; import java.nio.file.Files; @@ -34,17 +39,57 @@ public void testParseMethod() { @SneakyThrows @Test public void testClassInfo() { - String code = Files.readString(Paths.get("/tmp/o.java")); + String code = Files.readString(Paths.get("src/main/java/run/mone/ultraman/AthenaContext.java")); AthenaClassInfo info = AthenaCodeService.classInfo(code); System.out.println(info); System.out.println(info.getClassCode().length()); + + System.out.println("--------"); + info.getPublicMethodList().forEach(it -> { + System.out.println(it); + }); + System.out.println("-------"); + System.out.println(info.getClassCode()); + } + + @SneakyThrows + @Test + public void testAddDataAnnotationForClass() { + String code = Files.readString(Paths.get("/your path/PageBase.java")); + AthenaClassInfo athenaClassInfo = AthenaCodeService.classInfoWithDetail(code, true); + String newCode = FixCodeUtils.addDataAnnotationForClass(code, athenaClassInfo); + + System.out.println(newCode); + } + + @SneakyThrows + @Test + public void testAddBasicImportForClass() { + String code = Files.readString(Paths.get("/your path/SlaServiceImpl.java")); + AthenaClassInfo athenaClassInfo = AthenaCodeService.classInfoWithDetail(code, true); + String newCode = FixCodeUtils.addBasicImportForClass(code, athenaClassInfo); + + System.out.println(newCode); + } + + + @SneakyThrows + @Test + public void testParseCode() { + + String code = Files.readString(Paths.get("/your path/PageBase.java")); +// String code = Files.readString(Paths.get("/tmp/k")); +// String code = Files.readString(Paths.get("/tmp/o.java")); + List> info = AthenaCodeService.parseCode(code); + + System.out.println(info); } @SneakyThrows @Test public void testRemove() { - String code = Files.readString(Paths.get("/tmp/T.java")); + String code = Files.readString(Paths.get("/your path/T.java")); JavaParser javaParser = new JavaParser(); ParseResult pr = javaParser.parse(code); if (!pr.isSuccessful()) { @@ -52,10 +97,10 @@ public void testRemove() { } CompilationUnit cu = pr.getResult().get(); cu.findAll(MethodDeclaration.class).stream().filter(it -> it.isPrivate()).forEach(it -> it.removeForced()); - cu.findAll(ConstructorDeclaration.class).stream().forEach(it->it.getBody().removeForced()); + cu.findAll(ConstructorDeclaration.class).stream().forEach(it -> it.getBody().removeForced()); cu.findAll(InitializerDeclaration.class, init -> init.isStatic()).forEach(it -> it.removeForced()); - cu.findAll(FieldDeclaration.class).stream().forEach(it->it.removeForced()); + cu.findAll(FieldDeclaration.class).stream().forEach(it -> it.removeForced()); System.out.println(cu.toString()); } @@ -63,8 +108,33 @@ public void testRemove() { @SneakyThrows @Test public void testParseField() { - String code = Files.readString(Paths.get("/tmp/AthenaClassInfo.java")); + String code = Files.readString(Paths.get("/your path/AthenaClassInfo.java")); List fieldList = AthenaCodeService.parseFieldCode(code); System.out.println(fieldList); } + + + @Test + public void test1() { + String line = "for(int i=0;i<3;i++) {}"; + System.out.println(CaretHoverPlugin.isCompleteStatement("for(int i=0;i<3;i++) {}")); + } + + + + + private boolean containsUnclosedStructures(String lineText) { + int openBraces = 0; + int closeBraces = 0; + for (char c : lineText.toCharArray()) { + if (c == '{') { + openBraces++; + } else if (c == '}') { + closeBraces++; + } + } + return openBraces > closeBraces; + } + + } diff --git a/athena-all/src/test/java/run/mone/ultraman/test/Base64Test.java b/athena-all/src/test/java/run/mone/ultraman/test/Base64Test.java index 991612847..76af18a41 100644 --- a/athena-all/src/test/java/run/mone/ultraman/test/Base64Test.java +++ b/athena-all/src/test/java/run/mone/ultraman/test/Base64Test.java @@ -24,6 +24,7 @@ public class Base64Test { + @Test public void testa() throws InterruptedException { Instant begin = new Date().toInstant(); diff --git a/athena-all/src/test/java/run/mone/ultraman/test/BotTest.java b/athena-all/src/test/java/run/mone/ultraman/test/BotTest.java new file mode 100644 index 000000000..70a3e664d --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/BotTest.java @@ -0,0 +1,103 @@ +package run.mone.ultraman.test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableMap; +import com.google.gson.JsonObject; +import lombok.SneakyThrows; +import okhttp3.*; +import org.junit.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +/** + * @author goodjava@qq.com + * @date 2024/6/19 17:06 + */ +public class BotTest { + + @SneakyThrows + @Test + public void postBotQuery() throws IOException { + String url = ""; + + OkHttpClient client = new OkHttpClient(); + MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + + Map jsonMap = new HashMap<>(); + jsonMap.put("botId", "100336"); + jsonMap.put("userName", "zzy"); + jsonMap.put("input", ""); + jsonMap.put("params", ImmutableMap.of("input","hi")); + + ObjectMapper objectMapper = new ObjectMapper(); + String jsonString = objectMapper.writeValueAsString(jsonMap); + + RequestBody body = RequestBody.create(JSON, jsonString); + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + try (Response response = client.newCall(request).execute()) { + if (!response.isSuccessful()) { + throw new IOException("Unexpected code " + response); + } + System.out.println(response.body().string()); + } + } + + + @SneakyThrows + @Test + public void websocketBot() { + String url = ""; + + OkHttpClient client = new OkHttpClient(); + + JsonObject jsonReq = new JsonObject(); + jsonReq.addProperty("botId", ""); + jsonReq.addProperty("input", "hi"); + jsonReq.addProperty("topicId", UUID.randomUUID().toString()); + + Request request = new Request.Builder() + .url(url) + .header("athena-token", "") + .build(); + + WebSocketListener listener = new WebSocketListener() { + @Override + public void onOpen(WebSocket webSocket, Response response) { + System.out.println("WebSocket opened: " + response); + } + + @Override + public void onMessage(WebSocket webSocket, String text) { + System.out.println("Received message: " + text); + // 处理返回的信息 + } + + @Override + public void onClosing(WebSocket webSocket, int code, String reason) { + webSocket.close(1000, null); + System.out.println("WebSocket closing: " + code + " / " + reason); + } + + @Override + public void onFailure(WebSocket webSocket, Throwable t, Response response) { + t.printStackTrace(); + } + }; + + WebSocket webSocket = client.newWebSocket(request, listener); + + webSocket.send(jsonReq.toString()); + + TimeUnit.SECONDS.sleep(40); + client.dispatcher().executorService().shutdown(); + } + +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/CommonUtilsTest.java b/athena-all/src/test/java/run/mone/ultraman/test/CommonUtilsTest.java index 31243cd4c..d59a3925b 100644 --- a/athena-all/src/test/java/run/mone/ultraman/test/CommonUtilsTest.java +++ b/athena-all/src/test/java/run/mone/ultraman/test/CommonUtilsTest.java @@ -1,7 +1,6 @@ package run.mone.ultraman.test; import com.google.common.collect.Lists; -import run.mone.mone.ultraman.grpc.CommonUtils; import org.junit.Test; import java.util.Arrays; @@ -16,16 +15,6 @@ */ public class CommonUtilsTest { - @Test - public void testGetIntersection() { - CommonUtils commonUtils = new CommonUtils(); - List list1 = Arrays.asList("a", "b", "c", "d"); - List list2 = Arrays.asList("c", "d", "e", "f"); - List expected = Arrays.asList("c", "d"); - List actual = commonUtils.getIntersection(list1, list2); - assertEquals(expected, actual); - } - @Test public void testSubList() { diff --git a/athena-all/src/test/java/run/mone/ultraman/test/GsonTest.java b/athena-all/src/test/java/run/mone/ultraman/test/GsonTest.java index d13ac2298..69e9f6139 100644 --- a/athena-all/src/test/java/run/mone/ultraman/test/GsonTest.java +++ b/athena-all/src/test/java/run/mone/ultraman/test/GsonTest.java @@ -18,7 +18,6 @@ public void test1() { System.out.println(jsonObject.get("a").getAsString()); } - //计算两数和1 diff --git a/athena-all/src/test/java/run/mone/ultraman/test/MarkdownFilterTest.java b/athena-all/src/test/java/run/mone/ultraman/test/MarkdownFilterTest.java new file mode 100644 index 000000000..09941a1e3 --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/MarkdownFilterTest.java @@ -0,0 +1,45 @@ +package run.mone.ultraman.test; + +import com.xiaomi.youpin.tesla.ip.util.MarkdownFilter; +import org.junit.Test; + +/** + * @author goodjava@qq.com + * @date 2024/1/31 11:30 + */ +public class MarkdownFilterTest { + + @Test + public void testFilter() { + MarkdownFilter filter = new MarkdownFilter(System.out::print); + + filter.accept("Here is some text "); + filter.accept("and here is a code block: ```"); + filter.accept("java"); + filter.accept("System.out.println(\"Hello, world!\");"); + filter.accept("``` and now we're back to text."); + } + + @Test + public void testFilter2() { + MarkdownFilter filter = new MarkdownFilter(System.out::print); + filter.accept(""); + filter.accept("```"); + filter.accept("go"); + filter.accept("public void p(){"); + filter.accept("System.out.println(\"Hello, world! ```\");"); + filter.accept("}"); + filter.accept("```"); + filter.accept("\nend"); + System.out.println(""); + } + + @Test + public void testFilter3() { + MarkdownFilter filter = new MarkdownFilter(System.out::print); + filter.accept("public void p(){"); + filter.accept("System.out.println(\"Hello, world! ```\");"); + filter.accept("}"); + System.out.println(""); + } +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/NetUtilsTest.java b/athena-all/src/test/java/run/mone/ultraman/test/NetUtilsTest.java new file mode 100644 index 000000000..ddfb57e8f --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/NetUtilsTest.java @@ -0,0 +1,19 @@ +package run.mone.ultraman.test; + +import com.xiaomi.youpin.tesla.ip.util.NetUtils; +import org.junit.Test; + +import java.net.InetAddress; + +/** + * @author HawickMason@xiaomi.com + * @date 6/25/24 2:40 PM + */ +public class NetUtilsTest { + + @Test + public void testGetLocalAddress() { + String localAddress = NetUtils.getLocalHost(); + System.out.println("local ip:" + localAddress); + } +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/ScriptServiceTest.java b/athena-all/src/test/java/run/mone/ultraman/test/ScriptServiceTest.java index 47dcbc044..b61b1e8df 100644 --- a/athena-all/src/test/java/run/mone/ultraman/test/ScriptServiceTest.java +++ b/athena-all/src/test/java/run/mone/ultraman/test/ScriptServiceTest.java @@ -5,7 +5,7 @@ import com.google.common.collect.Maps; import com.google.common.io.Resources; import com.google.gson.Gson; -import run.mone.m78.ip.service.ScriptService; +import com.xiaomi.youpin.tesla.ip.service.ScriptService; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; diff --git a/athena-all/src/test/java/run/mone/ultraman/test/StringUtilsTest.java b/athena-all/src/test/java/run/mone/ultraman/test/StringUtilsTest.java new file mode 100644 index 000000000..091cf455f --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/StringUtilsTest.java @@ -0,0 +1,53 @@ +package run.mone.ultraman.test; + +import com.xiaomi.youpin.tesla.ip.common.StringUtils; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author goodjava@qq.com + * @date 2024/6/14 10:49 + */ +public class StringUtilsTest { + + + @Test + public void test1() { + String str = StringUtils.extractEndingKeyword("abc(class)"); + System.out.println(str); + } + + @Test + public void testExtractEndingKeyword() { + // Test case 1: Input string contains "(class)" + String input1 = "abc(class)"; + String result1 = StringUtils.extractEndingKeyword(input1); + System.out.println(result1); + + // Test case 2: Input string contains "(method)" + String input2 = "xyz(method)"; + String result2 = StringUtils.extractEndingKeyword(input2); + System.out.println(result2); + + // Test case 3: Input string contains "(project)" + String input3 = "test(project)"; + String result3 = StringUtils.extractEndingKeyword(input3); + System.out.println(result3); + // Test case 5: Input string does not contain any matching pattern + String input5 = "noMatch"; + String result5 = StringUtils.extractEndingKeyword(input5); + System.out.println("result5:" + result5); + + // Test case 6: Input string is aaa(class)bb + String input6 = "aaa(class)bb"; + String result6 = StringUtils.extractEndingKeyword(input6); + System.out.println("result6:" + result6); + + // Test case 7: Input string is xx\module + String input7 = "xx\\module"; + String result7 = StringUtils.extractEndingKeyword(input7); + System.out.println("result7:" + result7); + } + +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/TemplateTest.java b/athena-all/src/test/java/run/mone/ultraman/test/TemplateTest.java index 3231a47e3..c842bd469 100644 --- a/athena-all/src/test/java/run/mone/ultraman/test/TemplateTest.java +++ b/athena-all/src/test/java/run/mone/ultraman/test/TemplateTest.java @@ -1,8 +1,12 @@ package run.mone.ultraman.test; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import org.apache.commons.lang3.tuple.Pair; +import org.beetl.core.Context; +import org.beetl.core.Function; import org.junit.Test; import run.mone.ultraman.common.TemplateUtils; @@ -15,6 +19,19 @@ public class TemplateTest { + @Test + public void testCustomFunction() { + String result = TemplateUtils.renderTemplate("${greeting} ${customFunction('World')}", ImmutableMap.of("greeting", "Hello"), + Lists.newArrayList(Pair.of("customFunction", new Function() { + @Override + public Object call(Object[] paras, Context ctx) { + return "hahahaha:" + paras[0]; + } + }))); + System.out.println(result); + } + + @Test public void renderAndPrintTemplate() { String str = TemplateUtils.renderTemplate("${name} hi", ImmutableMap.of("name", "zzy")); @@ -40,15 +57,17 @@ public void printByteArrayAsString() { String v = (new String(data)); System.out.println(v); } - class A{ + + class A { public String x; public String y; } + @Test public void testOS() { System.out.println(System.getProperty("os.name")); - A a=new A(); - a.x="a"; + A a = new A(); + a.x = "a"; System.out.println(new Gson().toJson(a)); System.out.println(new GsonBuilder().serializeNulls().create().toJson(a)); } diff --git a/athena-all/src/test/java/run/mone/ultraman/test/VersionUtilTest.java b/athena-all/src/test/java/run/mone/ultraman/test/VersionUtilTest.java new file mode 100644 index 000000000..4815ab754 --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/VersionUtilTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2020 Xiaomi + * + * 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 run.mone.ultraman.test; + +import com.xiaomi.youpin.tesla.ip.common.VersionUtil; +import org.junit.Test; + +/** + * @author shanwb + * @date 2024-06-18 + */ +public class VersionUtilTest { + @Test + public void testCompareVersions() { + System.out.println(VersionUtil.compareVersions("2024.06.18.1", "2024.06.18.1") == 0); + System.out.println(VersionUtil.compareVersions("2024.7.18.1", "2024.06.18.1") > 0); + System.out.println(VersionUtil.compareVersions("2024.06.18.2", "2024.06.18.1") > 0); + System.out.println(VersionUtil.compareVersions("2024.06.18.1", "2024.06.18.2") < 0); + System.out.println(VersionUtil.compareVersions("2024.06.19.1", "2024.06.18.1") > 0); + System.out.println(VersionUtil.compareVersions("2024.06.18.1", "2024.06.19.1") < 0); + System.out.println(VersionUtil.compareVersions("2025.06.18.1", "2024.06.18.1") > 0); + System.out.println(VersionUtil.compareVersions("2024.06.18.1", "2025.06.18.1") < 0); + System.out.println(VersionUtil.compareVersions("2024.07.18.1", "2024.06.18.1") > 0); + System.out.println(VersionUtil.compareVersions("2024.06.18.1", "2024.07.18.1") < 0); + System.out.println(VersionUtil.compareVersions("2024.06.18.1", "2024.06.18") > 0); + System.out.println(VersionUtil.compareVersions("2024.06.18", "2024.06.18.1") < 0); + } + +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/WsClientTest.java b/athena-all/src/test/java/run/mone/ultraman/test/WsClientTest.java new file mode 100644 index 000000000..23acb9108 --- /dev/null +++ b/athena-all/src/test/java/run/mone/ultraman/test/WsClientTest.java @@ -0,0 +1,46 @@ +package run.mone.ultraman.test; + +import com.google.gson.JsonObject; +import lombok.SneakyThrows; +import org.junit.Test; +import run.mone.ultraman.http.WsClient; + +/** + * @author goodjava@qq.com + * @date 2024/5/30 13:38 + */ +public class WsClientTest { + + @SneakyThrows + @Test + public void test1() { + WsClient wc = new WsClient(); + wc.init(msg -> { + System.out.println(msg); + }); + wc.send(new JsonObject()); + System.in.read(); + } + + @SneakyThrows + public static void main(String[] args) { + WsClient wc = new WsClient(); + wc.init(msg->{ + System.out.println(msg); + }); + + JsonObject req = new JsonObject(); + + //req.addProperty("cmd","ping"); + + req.addProperty("botId", ""); + req.addProperty("input", "System.out.println(123);"); + req.addProperty("topicId", "123"); + + + wc.send(req); + + System.in.read(); + } + +} diff --git a/athena-all/src/test/java/run/mone/ultraman/test/XmlUtilsTest.java b/athena-all/src/test/java/run/mone/ultraman/test/XmlUtilsTest.java index 799c3146f..ddc3fc58f 100644 --- a/athena-all/src/test/java/run/mone/ultraman/test/XmlUtilsTest.java +++ b/athena-all/src/test/java/run/mone/ultraman/test/XmlUtilsTest.java @@ -1,6 +1,6 @@ package run.mone.ultraman.test; -import run.mone.m78.ip.util.XmlUtils; +import com.xiaomi.youpin.tesla.ip.util.XmlUtils; import org.junit.Test; import java.util.Map; @@ -13,12 +13,12 @@ public class XmlUtilsTest { @Test public void test1() { - XmlUtils.updateGeneratorConfig("/tmp/generatorConfig.xml","Abc"); + XmlUtils.updateGeneratorConfig("/your path/generatorConfig.xml","Abc"); } @Test public void test2() { - Map m = XmlUtils.getMysqlConfigFromMybatisConfig("/tmp/generatorConfig.xml"); + Map m = XmlUtils.getMysqlConfigFromMybatisConfig("/your path/generatorConfig.xml"); System.out.println(m); } } diff --git a/jcommon/codecheck/src/test/java/com/xiaomi/youpin/codecheck/test/CodeCheckTest.java b/jcommon/codecheck/src/test/java/com/xiaomi/youpin/codecheck/test/CodeCheckTest.java index bd2048db1..0388f5821 100644 --- a/jcommon/codecheck/src/test/java/com/xiaomi/youpin/codecheck/test/CodeCheckTest.java +++ b/jcommon/codecheck/src/test/java/com/xiaomi/youpin/codecheck/test/CodeCheckTest.java @@ -32,10 +32,18 @@ public class CodeCheckTest { @Test public void testCheckIP() { CodeCheck codeCheck = new CodeCheck(); - Map> map = codeCheck.check("/home/work/code/dubbo-demo/springboot-nacos-client-demo"); + Map> map = codeCheck.check("/home/work/mycode/ultraman"); map.entrySet().stream().forEach(it -> { System.out.println(it.getKey()); - it.getValue().stream().forEach(it1->System.out.println(it1)); + it.getValue().stream().forEach(it1->{ + String level = it1.getLevel(); + String name = it1.getName(); + if(!name.contains("idea-sandbox")) { + if (level.contains("ERROR")) { + System.out.println(it1); + } + } + }); System.out.println("\n"); }); } diff --git a/jcommon/codegen/pom.xml b/jcommon/codegen/pom.xml index a21ae573b..cfc3d4421 100644 --- a/jcommon/codegen/pom.xml +++ b/jcommon/codegen/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 run.mone @@ -61,5 +62,17 @@
+ + org.mybatis.generator + mybatis-generator-core + 1.4.0 + + + mysql + mysql-connector-java + 8.0.26 + + + diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/CodeGenerator.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/CodeGenerator.java new file mode 100644 index 000000000..57483329f --- /dev/null +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/CodeGenerator.java @@ -0,0 +1,114 @@ +package run.mone.ai.codegen; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import run.mone.ai.codegen.util.TemplateUtils; + +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +public class CodeGenerator { + + private final static Gson gson = new Gson(); + + private static String className = "E"; + + private static String testName = "T"; + + private static String serviceName = "s"; + + private static String basePath = "/Users/wodiwudi/java/nr-car-account"; + + private static boolean createPojo = false; + + private static boolean createVo = false; + + private static boolean createTransfer = false; + + private static boolean createService = false; + + private static boolean createTest = true; + + private static boolean createController = false; + + /** + * 主方法 + * 判断输入参数长度是否大于 0,调用方法处理参数并提取数据 + * 如果类名字符串为空则返回 + * 创建数据映射,放入相关数据 + * 根据模板文件和数据渲染并写入到相应文件(pojo.java、vo.java 等) + */ + public static void main(String[] args) { + Map map = null; + //方便ai调用的时候,设置表名 + if (args.length > 0) { + map = parseArgsAndExtractData(args); + className = map.get("pojoName"); + testName = map.get("testName"); + serviceName = map.get("serviceName"); + } + if (StringUtils.isEmpty(className)) { + return; + } + Map data = new HashMap<>(); + data.put("className", className); + data.put("author", "goodjava@qq.com"); + data.put("serviceName", serviceName); + Optional first = Arrays.stream(testName.split("\\.")).findFirst(); + data.put("testName", first.get()); + // 调用方法并获取结果 + if (createPojo) { + String pojo = TemplateUtils.renderTemplateFromFile("tlp/pojo.java", data); + TemplateUtils.writeStringToFile(pojo, basePath + "/your project/src/main/java/run/mone/model/po/" + className + ".java"); + } + + if (createVo) { + String vo = TemplateUtils.renderTemplateFromFile("tlp/vo.java", data); + TemplateUtils.writeStringToFile(vo, basePath + "/your project/src/main/java/run/mone/api/vo/" + className + "VO.java"); + } + + if (createTransfer) { + String transfer = TemplateUtils.renderTemplateFromFile("tlp/transfer.java", data); + TemplateUtils.writeStringToFile(transfer, basePath + "/your project/src/main/java/run/mone/model/transfer/" + className + "Transfer.java"); + } + + if (createService) { + String service = TemplateUtils.renderTemplateFromFile("tlp/service.java", data); + TemplateUtils.writeStringToFile(service, basePath + "/your project/src/main/java/run/mone/service/" + className + "Service.java"); + } + + if (createTest) { + String cn = testName; + System.out.println("create test:" + cn); + String test = TemplateUtils.renderTemplateFromFile("tlp/test.java", data); + TemplateUtils.writeStringToFile(test, basePath + "/your project/src/test/java/com/xiaomi/nr/car/account/constant/" + cn); + + } + + if (createController) { + String controller = TemplateUtils.renderTemplateFromFile("tlp/controller.java", data); + TemplateUtils.writeStringToFile(controller, basePath + "/your project/src/main/java/run/mone/controller/" + className + "Controller.java"); + } + } + + + private static Map parseArgsAndExtractData(String[] args) { + String jsonStr = args[0]; + Type typeOfT = new TypeToken>() { + }.getType(); + + jsonStr = new String(Base64.getDecoder().decode(jsonStr)); + log.info("jsonStr:{}", jsonStr); + + Map map = gson.fromJson(jsonStr, typeOfT); + log.info("map:{}", map); + return map; + } +} diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/FeatureGenerator.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/FeatureGenerator.java index 38812927d..e9ae8222d 100644 --- a/jcommon/codegen/src/main/java/run/mone/ai/codegen/FeatureGenerator.java +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/FeatureGenerator.java @@ -37,6 +37,7 @@ public static void generateWithTemplate(FeatureGenerateBo featureGenerateBo) { //配置数据源 HikariDataSource dataSource = new HikariDataSource(); + dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setJdbcUrl(featureGenerateBo.getJdbcUrl()); dataSource.setUsername(featureGenerateBo.getUserName()); dataSource.setPassword(featureGenerateBo.getPassword()); diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/MybatisGenerator.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/MybatisGenerator.java new file mode 100644 index 000000000..fdc0b99a5 --- /dev/null +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/MybatisGenerator.java @@ -0,0 +1,129 @@ +package run.mone.ai.codegen; + +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.generator.api.MyBatisGenerator; +import org.mybatis.generator.config.CommentGeneratorConfiguration; +import org.mybatis.generator.config.Configuration; +import org.mybatis.generator.config.Context; +import org.mybatis.generator.config.JDBCConnectionConfiguration; +import org.mybatis.generator.config.JavaClientGeneratorConfiguration; +import org.mybatis.generator.config.JavaModelGeneratorConfiguration; +import org.mybatis.generator.config.ModelType; +import org.mybatis.generator.config.PluginConfiguration; +import org.mybatis.generator.config.SqlMapGeneratorConfiguration; +import org.mybatis.generator.config.TableConfiguration; +import org.mybatis.generator.internal.DefaultShellCallback; +import run.mone.ai.codegen.bo.FeatureGenerateBo; + +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.Objects; + +@Slf4j +public class MybatisGenerator { + + private static final Gson gson = new Gson(); + + public static void main(String[] args) { + FeatureGenerateBo featureGenerateBo = null; + //方便ai调用的时候,设置表名 + if (args.length > 0) { + featureGenerateBo = parseArgsAndExtractData(args); + } + generateMyBatisFiles(featureGenerateBo); + } + + // 使用mybatis-generator生成指定表对应的XML、Mapper和Entity类 + public static void generateMyBatisFiles(FeatureGenerateBo featureGenerateBo) { + if (Objects.isNull(featureGenerateBo.getTableName())) { + log.warn("Table name is empty, cannot generate MyBatis files!"); + return; + } + // 配置MyBatis Generator + List warnings = new ArrayList<>(); + boolean overwrite = true; + Configuration config = new Configuration(); + + Context context = new Context(ModelType.FLAT); + context.setId("MyBatis3"); + context.setTargetRuntime("MyBatis3"); + + // 配置JDBC连接 + JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration(); + jdbcConnectionConfiguration.setDriverClass("com.mysql.cj.jdbc.Driver"); + jdbcConnectionConfiguration.setConnectionURL(featureGenerateBo.getJdbcUrl()); + jdbcConnectionConfiguration.setUserId(featureGenerateBo.getUserName()); + jdbcConnectionConfiguration.setPassword(featureGenerateBo.getPassword()); + context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration); + + // 配置Java模型生成器 + JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration(); + javaModelGeneratorConfiguration.setTargetPackage(featureGenerateBo.getMybatisDaoPath()); + javaModelGeneratorConfiguration.setTargetProject(featureGenerateBo.getMybatisDaoModule() + "/src/main/java"); + context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration); + + // 配置SQL映射生成器 + SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = new SqlMapGeneratorConfiguration(); + sqlMapGeneratorConfiguration.setTargetPackage(featureGenerateBo.getMybatisXMLPath()); + sqlMapGeneratorConfiguration.setTargetProject(featureGenerateBo.getMybatisDaoModule() + "/src/main/resources"); + context.setSqlMapGeneratorConfiguration(sqlMapGeneratorConfiguration); + + // 配置Java客户端生成器 + JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration(); + javaClientGeneratorConfiguration.setTargetPackage(featureGenerateBo.getMybatisDaoPath()); + javaClientGeneratorConfiguration.setTargetProject(featureGenerateBo.getMybatisDaoModule() + "/src/main/java"); + javaClientGeneratorConfiguration.setConfigurationType("XMLMAPPER"); + context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration); + + // 配置表 + TableConfiguration tableConfiguration = new TableConfiguration(context); + tableConfiguration.setTableName(featureGenerateBo.getTableName()); + tableConfiguration.setCountByExampleStatementEnabled(false); + tableConfiguration.setDeleteByExampleStatementEnabled(false); + tableConfiguration.setSelectByExampleStatementEnabled(false); + tableConfiguration.setUpdateByExampleStatementEnabled(false); + context.addTableConfiguration(tableConfiguration); + + // 配置 Comment Generator + CommentGeneratorConfiguration commentGeneratorConfiguration = new CommentGeneratorConfiguration(); + commentGeneratorConfiguration.addProperty("suppressAllComments", "true"); + context.setCommentGeneratorConfiguration(commentGeneratorConfiguration); + + // 配置自定义插件 + PluginConfiguration lombokConfiguration = new PluginConfiguration(); + lombokConfiguration.setConfigurationType("run.mone.ai.codegen.plugin.LombokPlugin"); + context.addPluginConfiguration(lombokConfiguration); + + PluginConfiguration removeGetSetMethodsPlugin = new PluginConfiguration(); + removeGetSetMethodsPlugin.setConfigurationType("run.mone.ai.codegen.plugin.RemoveGetSetMethodsPlugin"); + context.addPluginConfiguration(removeGetSetMethodsPlugin); + + config.addContext(context); + + DefaultShellCallback callback = new DefaultShellCallback(overwrite); + MyBatisGenerator myBatisGenerator; + try { + myBatisGenerator = new MyBatisGenerator(config, callback, warnings); + myBatisGenerator.generate(null); + } catch (Exception e) { + log.error("Error generating MyBatis files", e); + } + + if (!warnings.isEmpty()) { + warnings.forEach(log::warn); + } + } + + private static FeatureGenerateBo parseArgsAndExtractData(String[] args) { + String jsonStr = args[0]; + + jsonStr = new String(Base64.getDecoder().decode(jsonStr)); + log.info("jsonStr:{}", jsonStr); + + FeatureGenerateBo bo = gson.fromJson(jsonStr, FeatureGenerateBo.class); + log.info("map:{}", bo); + return bo; + } +} diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGeneratType.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGeneratType.java index 2773cc4e0..ba66ed583 100644 --- a/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGeneratType.java +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGeneratType.java @@ -15,7 +15,9 @@ public enum FeatureGeneratType { CODE_WITH_TEMPLATE(2, "使用预制模板生成"), - TABLE(3, "创建表"); + TABLE(3, "创建表"), + + CODE_WITH_MYBATIS_GENERATOR(4,"使用mybatis-generator生成"); private final int code; diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGenerateBo.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGenerateBo.java index cce56c8e3..e8c0fd450 100644 --- a/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGenerateBo.java +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/bo/FeatureGenerateBo.java @@ -4,6 +4,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import lombok.ToString; /** * @author goodjava@qq.com, HawickMason@xiaomi.com @@ -13,6 +14,7 @@ @AllArgsConstructor @Data @Builder +@ToString public class FeatureGenerateBo { @Builder.Default @@ -72,5 +74,17 @@ public class FeatureGenerateBo { @Builder.Default private boolean createController = false; - + + /** + * 目前使用module所在的绝对路径 + */ + @Builder.Default + private String mybatisDaoModule = ""; + @Builder.Default + private String mybatisXMLPath = ""; + @Builder.Default + private String mybatisDaoPath = ""; + @Builder.Default + private String mybatisEntityPath = ""; + } diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/plugin/LombokPlugin.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/plugin/LombokPlugin.java new file mode 100644 index 000000000..2458125d9 --- /dev/null +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/plugin/LombokPlugin.java @@ -0,0 +1,31 @@ +package run.mone.ai.codegen.plugin; + +import org.mybatis.generator.api.IntrospectedTable; +import org.mybatis.generator.api.PluginAdapter; +import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType; +import org.mybatis.generator.api.dom.java.TopLevelClass; + +import java.util.List; + +public class LombokPlugin extends PluginAdapter { + + @Override + public boolean validate(List warnings) { + // 该插件不需要任何配置,因此总是返回 true + return true; + } + + @Override + public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { + // 为生成的实体类添加 @Data 注解 + FullyQualifiedJavaType dataAnnotation = new FullyQualifiedJavaType("lombok.*"); + topLevelClass.addImportedType(dataAnnotation); + topLevelClass.addAnnotation("@Data"); + topLevelClass.addAnnotation("@ToString"); + topLevelClass.addAnnotation("@Builder"); + topLevelClass.addAnnotation("@AllArgsConstructor"); + topLevelClass.addAnnotation("@NoArgsConstructor"); + return true; + } +} + diff --git a/jcommon/codegen/src/main/java/run/mone/ai/codegen/plugin/RemoveGetSetMethodsPlugin.java b/jcommon/codegen/src/main/java/run/mone/ai/codegen/plugin/RemoveGetSetMethodsPlugin.java new file mode 100644 index 000000000..71929604b --- /dev/null +++ b/jcommon/codegen/src/main/java/run/mone/ai/codegen/plugin/RemoveGetSetMethodsPlugin.java @@ -0,0 +1,32 @@ +package run.mone.ai.codegen.plugin; + +import org.mybatis.generator.api.IntrospectedTable; +import org.mybatis.generator.api.PluginAdapter; +import org.mybatis.generator.api.dom.java.Method; +import org.mybatis.generator.api.dom.java.TopLevelClass; + +import java.util.Iterator; +import java.util.List; + +public class RemoveGetSetMethodsPlugin extends PluginAdapter { + + @Override + public boolean validate(List warnings) { + // 该插件不需要任何配置,因此总是返回 true + return true; + } + + @Override + public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) { + // 移除 get 和 set 方法 + Iterator methodIterator = topLevelClass.getMethods().iterator(); + while (methodIterator.hasNext()) { + Method method = methodIterator.next(); + if (method.getName().startsWith("get") || method.getName().startsWith("set")) { + methodIterator.remove(); + } + } + return true; + } +} + diff --git a/jcommon/codegen/src/test/java/com/xiaomi/youpin/codegen/test/FeatureGeneratorTest.java b/jcommon/codegen/src/test/java/com/xiaomi/youpin/codegen/test/FeatureGeneratorTest.java new file mode 100644 index 000000000..6acd2ef75 --- /dev/null +++ b/jcommon/codegen/src/test/java/com/xiaomi/youpin/codegen/test/FeatureGeneratorTest.java @@ -0,0 +1,49 @@ +package com.xiaomi.youpin.codegen.test; + +import org.junit.Test; +import run.mone.ai.codegen.FeatureGenerator; +import run.mone.ai.codegen.MybatisGenerator; +import run.mone.ai.codegen.bo.FeatureGeneratType; +import run.mone.ai.codegen.bo.FeatureGenerateBo; + +public class FeatureGeneratorTest { + + private String dbUrl = ""; + private String dbUser = ""; + private String dbPwd = ""; + + @Test + public void testCreateTable() { + FeatureGenerateBo featureGenerateBo = new FeatureGenerateBo(); + featureGenerateBo.setType(FeatureGeneratType.TABLE); + featureGenerateBo.setJdbcUrl(dbUrl); + featureGenerateBo.setUserName(dbUser); + featureGenerateBo.setPassword(dbPwd); + String sql = "CREATE TABLE IF NOT EXISTS `user` (\n" + + " `id` INT NOT NULL AUTO_INCREMENT,\n" + + " `name` VARCHAR(255) NOT NULL,\n" + + " `age` INT,\n" + + " PRIMARY KEY (`id`)\n" + + ");"; + featureGenerateBo.setSql(sql); + FeatureGenerator.generateWithTemplate(featureGenerateBo); + } + + @Test + public void testGenerateWithMybatis() { + FeatureGenerateBo featureGenerateBo = new FeatureGenerateBo(); + featureGenerateBo.setType(FeatureGeneratType.CODE_WITH_MYBATIS_GENERATOR); + featureGenerateBo.setJdbcUrl(dbUrl); + featureGenerateBo.setUserName(dbUser); + featureGenerateBo.setPassword(dbPwd); + featureGenerateBo.setTableName("user"); + + featureGenerateBo.setMybatisDaoModule("/your/path/mone/jcommon/codegen"); + featureGenerateBo.setMybatisXMLPath("com.xiaomi.dao.mapper"); + featureGenerateBo.setMybatisDaoPath("com.xiaomi.dao.mapper"); + featureGenerateBo.setMybatisEntityPath("com.xiaomi.dao.entity"); + + MybatisGenerator.generateMyBatisFiles(featureGenerateBo); + } + +} From e8793b4aca7961f8ee0b4a93ef9303566e8553cc Mon Sep 17 00:00:00 2001 From: dingpei Date: Tue, 6 Aug 2024 14:36:44 +0800 Subject: [PATCH 14/14] google ai support vision request --- jcommon/ai/google/pom.xml | 2 +- .../java/run/mone/ai/google/CloudeClient.java | 41 +++++-------------- .../google/bo/multiModal/GVisionContent.java | 19 +++++++++ .../ai/google/bo/multiModal/GVisionMsg.java | 23 +++++++++++ .../google/bo/multiModal/GVisionRequest.java | 32 +++++++++++++++ .../google/bo/multiModal/GVisionSource.java | 20 +++++++++ 6 files changed, 106 insertions(+), 31 deletions(-) create mode 100644 jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionContent.java create mode 100644 jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionMsg.java create mode 100644 jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionRequest.java create mode 100644 jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionSource.java diff --git a/jcommon/ai/google/pom.xml b/jcommon/ai/google/pom.xml index 6213e1dbc..74d000330 100644 --- a/jcommon/ai/google/pom.xml +++ b/jcommon/ai/google/pom.xml @@ -10,7 +10,7 @@ google - 1.4-jdk8-SNAPSHOT + 1.5-jdk8-SNAPSHOT 8 diff --git a/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java b/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java index 0c3722ff7..73ae7a864 100644 --- a/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java +++ b/jcommon/ai/google/src/main/java/run/mone/ai/google/CloudeClient.java @@ -12,6 +12,7 @@ import run.mone.ai.google.bo.Content; import run.mone.ai.google.bo.RequestPayload; import run.mone.ai.google.bo.ResponsePayload; +import run.mone.ai.google.bo.multiModal.GVisionRequest; import java.io.FileInputStream; import java.io.IOException; @@ -38,7 +39,6 @@ public class CloudeClient { private static Gson gson = new Gson(); - @SneakyThrows public String token(String model) { GoogleCredentials credentials = GoogleCredentials.fromStream( @@ -52,42 +52,23 @@ public String token(String model) { return this.token; } + public ResponsePayload visionCall(String url, String token, GVisionRequest GVisionRequest) { + return baseCall(url, token, gson.toJson(GVisionRequest)); + } public ResponsePayload call(String token, RequestPayload requestPayload) { - OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.MINUTES).build(); - MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); - RequestBody body = RequestBody.create(mediaType, new Gson().toJson(requestPayload)); - Request request = new Request.Builder() - .url(url + projectId + "/locations/us-central1/publishers/anthropic/models/" + model + ":streamRawPredict") - .post(body) - .addHeader("Authorization", "Bearer " + token) - .addHeader("Content-Type", "application/json; charset=utf-8") - .build(); + String callUrl = url + projectId + "/locations/us-central1/publishers/anthropic/models/" + model + ":streamRawPredict"; + return call(callUrl, token, requestPayload); + } - try (Response response = client.newCall(request).execute()) { - if (response.code() == 429) { - ResponsePayload res = new ResponsePayload(); - Content content = new Content(); - content.setText(gson.toJson(ImmutableMap.of("message", "被claude3限流了", "code", "429"))); - log.info("claude res:{}", content.getText()); - res.setContent(Lists.newArrayList(content)); - return res; - } - if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); - // Handle the response - String res = response.body().string(); - log.info("claude3 res:{}", res); - return new Gson().fromJson(res, ResponsePayload.class); - } catch (Throwable e) { - log.error(e.getMessage(), e); - } - return null; + public ResponsePayload call(String url, String token, RequestPayload requestPayload) { + return baseCall(url, token, gson.toJson(requestPayload)); } - public ResponsePayload call(String url ,String token, RequestPayload requestPayload) { + private ResponsePayload baseCall(String url, String token, String bodyStr) { OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.MINUTES).build(); MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); - RequestBody body = RequestBody.create(mediaType, new Gson().toJson(requestPayload)); + RequestBody body = RequestBody.create(mediaType, bodyStr); Request request = new Request.Builder() .url(url) .post(body) diff --git a/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionContent.java b/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionContent.java new file mode 100644 index 000000000..bff182901 --- /dev/null +++ b/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionContent.java @@ -0,0 +1,19 @@ +package run.mone.ai.google.bo.multiModal; + +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class GVisionContent { + + @SerializedName("type") + private String type; + + @SerializedName("text") + private String text; + + @SerializedName("source") + private GVisionSource source; +} diff --git a/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionMsg.java b/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionMsg.java new file mode 100644 index 000000000..6dc58d0f9 --- /dev/null +++ b/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionMsg.java @@ -0,0 +1,23 @@ +package run.mone.ai.google.bo.multiModal; + +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2023/5/25 14:16 + */ +@Data +@Builder +public class GVisionMsg implements Serializable { + + @SerializedName("role") + private String role; + + @SerializedName("content") + private List content; +} diff --git a/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionRequest.java b/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionRequest.java new file mode 100644 index 000000000..81a8600d7 --- /dev/null +++ b/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionRequest.java @@ -0,0 +1,32 @@ +package run.mone.ai.google.bo.multiModal; + +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * @author goodjava@qq.com + * @date 2024/4/9 16:36 + */ +@Data +@Builder +public class GVisionRequest { + + + @SerializedName("anthropic_version") + private String anthropicVersion; + + @SerializedName("messages") + private List messages; + + @SerializedName("max_tokens") + private int maxTokens; + + @SerializedName("stream") + private boolean stream; + + + +} diff --git a/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionSource.java b/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionSource.java new file mode 100644 index 000000000..277aa9d08 --- /dev/null +++ b/jcommon/ai/google/src/main/java/run/mone/ai/google/bo/multiModal/GVisionSource.java @@ -0,0 +1,20 @@ +package run.mone.ai.google.bo.multiModal; + +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class GVisionSource { + + @SerializedName("type") + private String type; + + @SerializedName("media_type") + private String mediaType; + + @SerializedName("data") + private String data; + +}