From 749520d4daf020e502663cb8cafd65f6a56ea744 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 16 Mar 2021 18:43:42 +0800 Subject: [PATCH 001/121] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/core/lexer/action/BorderAction.java | 2 +- .../sum/spirit/core/lexer/action/RegionAction.java | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java index e26c54ff..67792e8a 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java @@ -14,7 +14,7 @@ import com.sum.spirit.core.lexer.entity.Region; public class BorderAction extends RegionAction { @Override - public void doPushStack(CharEvent event, List regions, String markName) { + public void pushStack(CharEvent event, List regions, String markName) { LexerContext context = (LexerContext) event.context; StringBuilder builder = context.builder; diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java index e73c8db1..e9ce7b9d 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java @@ -51,20 +51,20 @@ public class RegionAction extends AbstractLexerAction { if (ch == '"') { Region region = findRegion(builder, context.index, '"', '"'); - doPushStack(event, Lists.toList(region), "@str"); + pushStack(event, Lists.toList(region), "@str"); } else if (ch == '\'') { Region region = findRegion(builder, context.index, '\'', '\''); - doPushStack(event, Lists.toList(region), "@char"); + pushStack(event, Lists.toList(region), "@char"); } else if (ch == '{') { Region region = findRegion(builder, context.index, '{', '}'); - doPushStack(event, Lists.toList(region), "@map"); + pushStack(event, Lists.toList(region), "@map"); } else if (ch == '(') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; Region region1 = findRegion(builder, context.index, '(', ')'); - doPushStack(event, Lists.toList(region0, region1), "@invoke_like"); + pushStack(event, Lists.toList(region0, region1), "@invoke_like"); resetIndex(event); } else if (ch == '[') { @@ -77,14 +77,14 @@ public class RegionAction extends AbstractLexerAction { } else if (isCharAt(builder, region1.endIndex, ' ') && isCharAt(builder, region1.endIndex + 1, '{')) { region2 = findRegion(builder, region1.endIndex + 1, '{', '}'); } - doPushStack(event, Lists.toList(region0, region1, region2), "@array_like"); + pushStack(event, Lists.toList(region0, region1, region2), "@array_like"); resetIndex(event); } else if (ch == '<') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; Region region1 = findRegion(builder, context.index, '<', '>'); Region region2 = isCharAt(builder, region1.endIndex, '(') ? findRegion(builder, region1.endIndex, '(', ')') : null; - doPushStack(event, Lists.toList(region0, region1, region2), "@generic"); + pushStack(event, Lists.toList(region0, region1, region2), "@generic"); resetIndex(event); } } @@ -93,7 +93,7 @@ public class RegionAction extends AbstractLexerAction { return index < builder.length() && builder.charAt(index) == ch; } - public void doPushStack(CharEvent event, List regions, String markName) { + public void pushStack(CharEvent event, List regions, String markName) { LexerContext context = (LexerContext) event.context; replaceRegion(context.builder, mergeRegions(regions), markName + context.nameCount++, context.replacedStrs); } -- Gitee From 8e8ce20fa2afa519ab1390f91302d30441145701 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 16 Mar 2021 21:22:21 +0800 Subject: [PATCH 002/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=80=E7=A7=8D?= =?UTF-8?q?=E6=95=B0=E7=BB=84token=E7=B1=BB=E5=9E=8B=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=8E=A8=E5=AF=BC=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/common/enums/TokenTypeEnum.java | 5 ++- .../com/sum/spirit/common/enums/TypeEnum.java | 13 ++++++++ .../compile/deduce/InvocationVisiter.java | 13 +++----- .../core/compile/deduce/VariableTracker.java | 6 ---- .../action/AbstractSemanticParser.java | 31 ++++++++--------- .../core/element/entity/SyntaxTree.java | 2 +- .../spirit/core/element/frame/Semantic.java | 18 ++++------ .../lexer/action/AbstractLexerAction.java | 4 +++ .../core/lexer/action/RegionAction.java | 16 ++++++--- .../sum/spirit/core/lexer/test/LexerTest.java | 33 ++++++++++++++----- .../src/test/java/com/sum/test/type/Type.java | 6 ++++ 11 files changed, 88 insertions(+), 59 deletions(-) create mode 100644 spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java index ef831396..811d7606 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java @@ -23,9 +23,8 @@ public enum TokenTypeEnum { VARIABLE, // 变量 LOCAL_METHOD, // 本地方法 VISIT_FIELD, // 访问字段 - INVOKE_METHOD, // 调用方法 - VISIT_ARRAY_INDEX, // 访问字段,并通过索引访问数组中的元素 - ARRAY_INDEX, // 访问字段,并通过索引访问数组中的元素 + VISIT_METHOD, // 调用方法 + VISIT_INDEX, // 访问数组 PREFIX, // 前缀 CUSTOM_PREFIX, // 自定义前缀 CUSTOM_SUFFIX, // 自定义后缀 diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java new file mode 100644 index 00000000..ecf65f90 --- /dev/null +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java @@ -0,0 +1,13 @@ +package com.sum.spirit.common.enums; + +import java.util.regex.Pattern; + +public class TypeEnum { + ; + public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); + public static final Pattern TYPE_PATTERN = Pattern.compile("^[A-Z]+\\w*$"); + + public static boolean isPureType(String prefix) { + return PrimitiveEnum.isPrimitiveBySimple(prefix) || (!CONST_VAR_PATTERN.matcher(prefix).matches() && TYPE_PATTERN.matcher(prefix).matches()); + } +} diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java index 7654b08e..f620fddb 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java @@ -35,8 +35,7 @@ public class InvocationVisiter { continue; } List parameterTypes = token.isInvoke() ? getParameterTypes(clazz, token) : null; - if (token.isType() || token.isArrayInit() || token.isTypeInit() || // - token.isCast() || token.isValue()) { + if (token.isType() || token.isArrayInit() || token.isTypeInit() || token.isCast() || token.isValue()) { token.setAttr(AttributeEnum.TYPE, factory.create(clazz, token)); } else if (token.isSubexpress()) { @@ -54,18 +53,16 @@ public class InvocationVisiter { IType returnType = linker.visitField(type, memberName); token.setAttr(AttributeEnum.TYPE, returnType); - } else if (token.isInvokeMethod()) { + } else if (token.isVisitMethod()) { IType type = stmt.get(index - 1).attr(AttributeEnum.TYPE); String memberName = token.attr(AttributeEnum.MEMBER_NAME); IType returnType = linker.visitMethod(type, memberName, parameterTypes); token.setAttr(AttributeEnum.TYPE, returnType); - } else if (token.isVisitArrayIndex()) {// what like ".str[0]" + } else if (token.isVisitIndex()) {// what like "[0]" IType type = stmt.get(index - 1).attr(AttributeEnum.TYPE); - String memberName = token.attr(AttributeEnum.MEMBER_NAME); - IType returnType = linker.visitField(type, memberName); - returnType = factory.create(returnType.getTargetName()); - token.setAttr(AttributeEnum.TYPE, returnType); + type = derivator.toTarget(type);// 转换数组类型为目标类型 + token.setAttr(AttributeEnum.TYPE, type); } } catch (NoSuchFieldException | NoSuchMethodException e) { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java index f7fd8be8..08ffc59b 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java @@ -40,12 +40,6 @@ public class VariableTracker { IType type = getVariableType(clazz, context, variableName); token.setAttr(AttributeEnum.TYPE, type); - } else if (token.isArrayIndex()) {// .strs[0] - String memberName = token.attr(AttributeEnum.MEMBER_NAME); - IType type = getVariableType(clazz, context, memberName); - type = derivator.toTarget(type);// 转换数组类型为目标类型 - token.setAttr(AttributeEnum.TYPE, type); - } else if (token.isKeyword() && KeywordEnum.isKeywordVariable(token.getValue())) { String variableName = token.toString(); IType type = findTypeByKeyword(clazz, variableName); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index ab4270c9..09003ef2 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -37,13 +37,12 @@ public abstract class AbstractSemanticParser implements SemanticParser { public static final Pattern MAP_PATTERN = Pattern.compile("^\\{[\\s\\S]*\\}$"); public static final Pattern SUBEXPRESS_PATTERN = Pattern.compile("^\\([\\s\\S]+\\)$"); - public static final Pattern VAR_PATTERN = Pattern.compile("^[a-z]+\\w*$"); public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); - public static final Pattern INVOKE_LOCAL_PATTERN = Pattern.compile("^[a-z]+\\w*\\([\\s\\S]*\\)$"); + public static final Pattern VAR_PATTERN = Pattern.compile("^[a-z]+\\w*$"); + public static final Pattern LOCAL_METHOD_PATTERN = Pattern.compile("^[a-z]+\\w*\\([\\s\\S]*\\)$"); public static final Pattern VISIT_FIELD_PATTERN = Pattern.compile("^\\.[a-z]+\\w*$"); - public static final Pattern INVOKE_METHOD_PATTERN = Pattern.compile("^\\.[a-z]+\\w*\\([\\s\\S]*\\)$"); - public static final Pattern VISIT_ARRAY_INDEX_PATTERN = Pattern.compile("^\\.[a-z]+\\w*\\[\\d+\\]$"); - public static final Pattern ARRAY_INDEX_PATTERN = Pattern.compile("^[a-z]+\\w*\\[\\d+\\]$"); + public static final Pattern VISIT_METHOD_PATTERN = Pattern.compile("^\\.[a-z]+\\w*\\([\\s\\S]*\\)$"); + public static final Pattern VISIT_INDEX_PATTERN = Pattern.compile("^\\[\\d+\\]$"); public static final Pattern PREFIX_PATTERN = Pattern.compile("^(\\.)?\\w+$"); @@ -109,7 +108,7 @@ public abstract class AbstractSemanticParser implements SemanticParser { LONG_PATTERN.matcher(word).matches() || // DOUBLE_PATTERN.matcher(word).matches() || // STR_PATTERN.matcher(word).matches() || // - LIST_PATTERN.matcher(word).matches() || // + (!VISIT_INDEX_PATTERN.matcher(word).matches() && LIST_PATTERN.matcher(word).matches()) || // not be "[0]" MAP_PATTERN.matcher(word).matches(); } @@ -125,11 +124,10 @@ public abstract class AbstractSemanticParser implements SemanticParser { @Override public boolean isAccess(String word) { - return INVOKE_LOCAL_PATTERN.matcher(word).matches() || // + return LOCAL_METHOD_PATTERN.matcher(word).matches() || // VISIT_FIELD_PATTERN.matcher(word).matches() || // - INVOKE_METHOD_PATTERN.matcher(word).matches() || // - VISIT_ARRAY_INDEX_PATTERN.matcher(word).matches() || // - ARRAY_INDEX_PATTERN.matcher(word).matches(); + VISIT_METHOD_PATTERN.matcher(word).matches() || // + VISIT_INDEX_PATTERN.matcher(word).matches(); } public TokenTypeEnum getInitTokenType(String word) { @@ -190,20 +188,17 @@ public abstract class AbstractSemanticParser implements SemanticParser { } public TokenTypeEnum getAccessTokenType(String word) { - if (INVOKE_LOCAL_PATTERN.matcher(word).matches()) { + if (LOCAL_METHOD_PATTERN.matcher(word).matches()) { return TokenTypeEnum.LOCAL_METHOD; } if (VISIT_FIELD_PATTERN.matcher(word).matches()) { return TokenTypeEnum.VISIT_FIELD; } - if (INVOKE_METHOD_PATTERN.matcher(word).matches()) { - return TokenTypeEnum.INVOKE_METHOD; - } - if (VISIT_ARRAY_INDEX_PATTERN.matcher(word).matches()) { - return TokenTypeEnum.VISIT_ARRAY_INDEX; + if (VISIT_METHOD_PATTERN.matcher(word).matches()) { + return TokenTypeEnum.VISIT_METHOD; } - if (ARRAY_INDEX_PATTERN.matcher(word).matches()) { - return TokenTypeEnum.ARRAY_INDEX; + if (VISIT_INDEX_PATTERN.matcher(word).matches()) { + return TokenTypeEnum.VISIT_INDEX; } return null; } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java index deab95ff..9596fbd3 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java @@ -109,7 +109,7 @@ public class SyntaxTree { } else if (prevToken.isVisitField()) {// var.text = "abc" return SyntaxEnum.FIELD_ASSIGN; } - } else if (firstToken.isInvokeMethod()) {// list.get(0) + } else if (firstToken.isVisitMethod()) {// list.get(0) return SyntaxEnum.INVOKE; } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java index 7954a3cc..5173967d 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java @@ -100,16 +100,12 @@ public abstract class Semantic extends AttributeMap { return tokenType == TokenTypeEnum.VISIT_FIELD; } - public boolean isInvokeMethod() { - return tokenType == TokenTypeEnum.INVOKE_METHOD; + public boolean isVisitMethod() { + return tokenType == TokenTypeEnum.VISIT_METHOD; } - public boolean isVisitArrayIndex() { - return tokenType == TokenTypeEnum.VISIT_ARRAY_INDEX; - } - - public boolean isArrayIndex() { - return tokenType == TokenTypeEnum.ARRAY_INDEX; + public boolean isVisitIndex() { + return tokenType == TokenTypeEnum.VISIT_INDEX; } public boolean isPrefix() { @@ -141,15 +137,15 @@ public abstract class Semantic extends AttributeMap { } public boolean isAccess() { - return isLocalMethod() || isVisitField() || isInvokeMethod() || isVisitArrayIndex() || isArrayIndex(); + return isLocalMethod() || isVisitField() || isVisitMethod() || isVisitIndex(); } public boolean isInvoke() { - return isTypeInit() || isLocalMethod() || isInvokeMethod(); + return isTypeInit() || isLocalMethod() || isVisitMethod(); } public boolean isFluent() { - return isVisitField() || isInvokeMethod() || isVisitArrayIndex(); + return isVisitField() || isVisitMethod() || isVisitIndex(); } public boolean canSplit() { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java index c07c4082..5827886c 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java @@ -18,6 +18,10 @@ public abstract class AbstractLexerAction implements CharAction { return endIndex != -1 ? new Region(fromIndex, endIndex + 1) : null; } + public String subRegion(StringBuilder builder, Region region) { + return builder.substring(region.startIndex, region.endIndex); + } + public Region mergeRegions(List regions) { Region finalRegion = new Region(-1, -1); for (Region region : regions) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java index e9ce7b9d..5f53f23d 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java @@ -5,6 +5,7 @@ import java.util.List; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import com.sum.spirit.common.enums.TypeEnum; import com.sum.spirit.common.utils.Lists; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; @@ -69,13 +70,20 @@ public class RegionAction extends AbstractLexerAction { } else if (ch == '[') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; + // 前缀必须是类型才合并 + if (region0 != null && !TypeEnum.isPureType(subRegion(builder, region0))) { + region0 = null; + } Region region1 = findRegion(builder, context.index, '[', ']'); + // 必须有前缀才解析 Region region2 = null; - if (isCharAt(builder, region1.endIndex, '{')) { - region2 = findRegion(builder, region1.endIndex, '{', '}'); + if (region0 != null) { + if (isCharAt(builder, region1.endIndex, '{')) { + region2 = findRegion(builder, region1.endIndex, '{', '}'); - } else if (isCharAt(builder, region1.endIndex, ' ') && isCharAt(builder, region1.endIndex + 1, '{')) { - region2 = findRegion(builder, region1.endIndex + 1, '{', '}'); + } else if (isCharAt(builder, region1.endIndex, ' ') && isCharAt(builder, region1.endIndex + 1, '{')) { + region2 = findRegion(builder, region1.endIndex + 1, '{', '}'); + } } pushStack(event, Lists.toList(region0, region1, region2), "@array_like"); resetIndex(event); diff --git a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java index 3a532e60..deaf2fa3 100644 --- a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java +++ b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java @@ -237,7 +237,7 @@ public class LexerTest { } @Test - @DisplayName("字段访问") + @DisplayName("访问字段") public void test0014() { String text = "fatherName = people.father.name"; List words = lexer.getWords(text); @@ -252,7 +252,7 @@ public class LexerTest { } @Test - @DisplayName("方法访问") + @DisplayName("访问方法") public void test0015() { String text = "fatherName = people.father().name()"; List words = lexer.getWords(text); @@ -267,23 +267,40 @@ public class LexerTest { } @Test - @DisplayName("数组字段访问") + @DisplayName("访问字段数组索引") public void test0016() { String text = "fatherName = people.father().name[0]"; List words = lexer.getWords(text); log.info(words.toString()); - assertTrue(words.size() == 5); + assertTrue(words.size() == 6); int count = 0; assertEquals(words.get(count++), "fatherName"); assertEquals(words.get(count++), "="); assertEquals(words.get(count++), "people"); assertEquals(words.get(count++), ".father()"); - assertEquals(words.get(count++), ".name[0]"); + assertEquals(words.get(count++), ".name"); + assertEquals(words.get(count++), "[0]"); } @Test - @DisplayName("操作符逻辑") + @DisplayName("访问方法数组索引") public void test0017() { + String text = "fatherName = people.father().name()[0]"; + List words = lexer.getWords(text); + log.info(words.toString()); + assertTrue(words.size() == 6); + int count = 0; + assertEquals(words.get(count++), "fatherName"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "people"); + assertEquals(words.get(count++), ".father()"); + assertEquals(words.get(count++), ".name()"); + assertEquals(words.get(count++), "[0]"); + } + + @Test + @DisplayName("逻辑操作符") + public void test0018() { String text = "flag = !(x+1>0 && y<100) && s==\"test\" || s instanceof Object"; List words = lexer.getWords(text); log.info(words.toString()); @@ -304,8 +321,8 @@ public class LexerTest { } @Test - @DisplayName("操作符计算") - public void test0018() { + @DisplayName("计算操作符") + public void test0019() { String text = "number = x%2*100/2 + y - z"; List words = lexer.getWords(text); log.info(words.toString()); diff --git a/spirit-test/src/test/java/com/sum/test/type/Type.java b/spirit-test/src/test/java/com/sum/test/type/Type.java index 2a0a3403..bbcc0070 100644 --- a/spirit-test/src/test/java/com/sum/test/type/Type.java +++ b/spirit-test/src/test/java/com/sum/test/type/Type.java @@ -102,6 +102,8 @@ public class Type { final String strxxxx; strxxxx = "hello"; logger.info(strxxxx); + boolean bbxxx = getArray()[0]; + logger.info("" + bbxxx); } public String testParam(@Deprecated String str, Object obj) { @@ -113,4 +115,8 @@ public class Type { return "I am a Str!" + anumx; } + public boolean[] getArray() { + return bArray; + } + } -- Gitee From 7bc5f045bba7a57228e6d0223b0175bb10168688 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 16 Mar 2021 21:22:33 +0800 Subject: [PATCH 003/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spirit-test/src/test/resources/com.sum.test/type/Type.sp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spirit-test/src/test/resources/com.sum.test/type/Type.sp b/spirit-test/src/test/resources/com.sum.test/type/Type.sp index 760d35d4..c788a565 100644 --- a/spirit-test/src/test/resources/com.sum.test/type/Type.sp +++ b/spirit-test/src/test/resources/com.sum.test/type/Type.sp @@ -127,6 +127,8 @@ class Type { strxxxx="hello" print strxxxx + bbxxx=getArray()[0] + print "" + bbxxx } func testParam(@Deprecated String str, Object obj){ @@ -137,5 +139,9 @@ class Type { anumx=1111 return "I am a Str!" + anumx } + + func getArray(){ + return bArray + } } \ No newline at end of file -- Gitee From c94ec91986842361eaa7060b64f7b39cd8a4ce3d Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 16 Mar 2021 21:33:31 +0800 Subject: [PATCH 004/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E5=88=A0=E9=99=A4=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E5=88=86=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/core/element/action/AbstractSemanticParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index 09003ef2..1eac7b33 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -33,7 +33,7 @@ public abstract class AbstractSemanticParser implements SemanticParser { public static final Pattern LONG_PATTERN = Pattern.compile("^\\d+L$"); public static final Pattern DOUBLE_PATTERN = Pattern.compile("^\\d+\\.\\d+$"); public static final Pattern STR_PATTERN = Pattern.compile("^\"[\\s\\S]*\"$"); - public static final Pattern LIST_PATTERN = Pattern.compile("^\\[[\\s\\S]*\\]$"); + public static final Pattern LIST_PATTERN = Pattern.compile("^\\[[\\s\\S]*\\]$");// list can`t be "[0]" public static final Pattern MAP_PATTERN = Pattern.compile("^\\{[\\s\\S]*\\}$"); public static final Pattern SUBEXPRESS_PATTERN = Pattern.compile("^\\([\\s\\S]+\\)$"); -- Gitee From a6165811eca66786e605cf267786efe5eb1d6aac Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Wed, 17 Mar 2021 18:45:18 +0800 Subject: [PATCH 005/121] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/element/action/TreeBuilderImpl.java | 2 +- .../main/java/com/sum/spirit/core/element/frame/Semantic.java | 2 +- .../main/java/com/sum/spirit/core/element/utils/StmtFormat.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/TreeBuilderImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/TreeBuilderImpl.java index daed755f..118e3dfb 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/TreeBuilderImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/TreeBuilderImpl.java @@ -45,7 +45,7 @@ public class TreeBuilderImpl extends AbstractTreeBuilder { int priority = -1; OperandEnum operand = null; - if (currentToken.isFluent()) { + if (currentToken.isVisit()) { priority = 55; operand = OperandEnum.LEFT; diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java index 5173967d..c99fc151 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java @@ -144,7 +144,7 @@ public abstract class Semantic extends AttributeMap { return isTypeInit() || isLocalMethod() || isVisitMethod(); } - public boolean isFluent() { + public boolean isVisit() { return isVisitField() || isVisitMethod() || isVisitIndex(); } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java index 5187f454..70692919 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java @@ -77,7 +77,7 @@ public class StmtFormat { } } - } else if (nextToken.isFluent()) { + } else if (nextToken.isVisit()) { tokens.remove(i); continue; -- Gitee From a534bc444a09db38e5bac092d600b9595002955f Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Wed, 17 Mar 2021 19:28:10 +0800 Subject: [PATCH 006/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AD=97=E9=9D=A2?= =?UTF-8?q?=E5=80=BC=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/common/enums/LiteralEnum.java | 16 ++++++ .../action/AbstractSemanticParser.java | 49 ++++++++----------- 2 files changed, 36 insertions(+), 29 deletions(-) create mode 100644 spirit-common/src/main/java/com/sum/spirit/common/enums/LiteralEnum.java diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/LiteralEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/LiteralEnum.java new file mode 100644 index 00000000..7787629e --- /dev/null +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/LiteralEnum.java @@ -0,0 +1,16 @@ +package com.sum.spirit.common.enums; + +import java.util.regex.Pattern; + +public enum LiteralEnum { + ; + public static final Pattern NULL_PATTERN = Pattern.compile("^null$"); + public static final Pattern BOOLEAN_PATTERN = Pattern.compile("^(true|false)$"); + public static final Pattern CHAR_PATTERN = Pattern.compile("^'[\\s\\S]*'$"); + public static final Pattern INT_PATTERN = Pattern.compile("^\\d+$"); + public static final Pattern LONG_PATTERN = Pattern.compile("^\\d+L$"); + public static final Pattern DOUBLE_PATTERN = Pattern.compile("^\\d+\\.\\d+$"); + public static final Pattern STRING_PATTERN = Pattern.compile("^\"[\\s\\S]*\"$"); + public static final Pattern LIST_PATTERN = Pattern.compile("^\\[[\\s\\S]*\\]$"); + public static final Pattern MAP_PATTERN = Pattern.compile("^\\{[\\s\\S]*\\}$"); +} diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index 1eac7b33..51a38da7 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.regex.Pattern; import com.sum.spirit.common.enums.KeywordEnum; +import com.sum.spirit.common.enums.LiteralEnum; import com.sum.spirit.common.enums.PrimitiveEnum; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.TokenTypeEnum; @@ -26,16 +27,6 @@ public abstract class AbstractSemanticParser implements SemanticParser { public static final Pattern TYPE_ARRAY_CERTAIN_INIT_PATTERN = Pattern.compile("^[A-Z]+\\w*\\[\\]\\{[\\s\\S]*\\}$"); public static final Pattern TYPE_INIT_PATTERN = Pattern.compile("^[A-Z]+\\w*(<[\\s\\S]+>)?\\([\\s\\S]*\\)$"); - public static final Pattern NULL_PATTERN = Pattern.compile("^null$"); - public static final Pattern BOOL_PATTERN = Pattern.compile("^(true|false)$"); - public static final Pattern CHAR_PATTERN = Pattern.compile("^'[\\s\\S]*'$"); - public static final Pattern INT_PATTERN = Pattern.compile("^\\d+$"); - public static final Pattern LONG_PATTERN = Pattern.compile("^\\d+L$"); - public static final Pattern DOUBLE_PATTERN = Pattern.compile("^\\d+\\.\\d+$"); - public static final Pattern STR_PATTERN = Pattern.compile("^\"[\\s\\S]*\"$"); - public static final Pattern LIST_PATTERN = Pattern.compile("^\\[[\\s\\S]*\\]$");// list can`t be "[0]" - public static final Pattern MAP_PATTERN = Pattern.compile("^\\{[\\s\\S]*\\}$"); - public static final Pattern SUBEXPRESS_PATTERN = Pattern.compile("^\\([\\s\\S]+\\)$"); public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); public static final Pattern VAR_PATTERN = Pattern.compile("^[a-z]+\\w*$"); @@ -57,7 +48,7 @@ public abstract class AbstractSemanticParser implements SemanticParser { @Override public boolean isPath(String word) { - return !DOUBLE_PATTERN.matcher(word).matches() && PATH_PATTERN.matcher(word).matches(); + return !LiteralEnum.DOUBLE_PATTERN.matcher(word).matches() && PATH_PATTERN.matcher(word).matches(); } @Override @@ -101,15 +92,15 @@ public abstract class AbstractSemanticParser implements SemanticParser { @Override public boolean isValue(String word) { - return NULL_PATTERN.matcher(word).matches() || // - BOOL_PATTERN.matcher(word).matches() || // - CHAR_PATTERN.matcher(word).matches() || // - INT_PATTERN.matcher(word).matches() || // - LONG_PATTERN.matcher(word).matches() || // - DOUBLE_PATTERN.matcher(word).matches() || // - STR_PATTERN.matcher(word).matches() || // - (!VISIT_INDEX_PATTERN.matcher(word).matches() && LIST_PATTERN.matcher(word).matches()) || // not be "[0]" - MAP_PATTERN.matcher(word).matches(); + return LiteralEnum.NULL_PATTERN.matcher(word).matches() || // + LiteralEnum.BOOLEAN_PATTERN.matcher(word).matches() || // + LiteralEnum.CHAR_PATTERN.matcher(word).matches() || // + LiteralEnum.INT_PATTERN.matcher(word).matches() || // + LiteralEnum.LONG_PATTERN.matcher(word).matches() || // + LiteralEnum.DOUBLE_PATTERN.matcher(word).matches() || // + LiteralEnum.STRING_PATTERN.matcher(word).matches() || // + (!VISIT_INDEX_PATTERN.matcher(word).matches() && LiteralEnum.LIST_PATTERN.matcher(word).matches()) || // not be "[0]" + LiteralEnum.MAP_PATTERN.matcher(word).matches(); } @Override @@ -150,31 +141,31 @@ public abstract class AbstractSemanticParser implements SemanticParser { } public TokenTypeEnum getValueTokenType(String word) { - if (NULL_PATTERN.matcher(word).matches()) { + if (LiteralEnum.NULL_PATTERN.matcher(word).matches()) { return TokenTypeEnum.NULL; } - if (BOOL_PATTERN.matcher(word).matches()) { + if (LiteralEnum.BOOLEAN_PATTERN.matcher(word).matches()) { return TokenTypeEnum.BOOL; } - if (CHAR_PATTERN.matcher(word).matches()) { + if (LiteralEnum.CHAR_PATTERN.matcher(word).matches()) { return TokenTypeEnum.CHAR; } - if (INT_PATTERN.matcher(word).matches()) { + if (LiteralEnum.INT_PATTERN.matcher(word).matches()) { return TokenTypeEnum.INT; } - if (LONG_PATTERN.matcher(word).matches()) { + if (LiteralEnum.LONG_PATTERN.matcher(word).matches()) { return TokenTypeEnum.LONG; } - if (DOUBLE_PATTERN.matcher(word).matches()) { + if (LiteralEnum.DOUBLE_PATTERN.matcher(word).matches()) { return TokenTypeEnum.DOUBLE; } - if (STR_PATTERN.matcher(word).matches()) { + if (LiteralEnum.STRING_PATTERN.matcher(word).matches()) { return TokenTypeEnum.STRING; } - if (LIST_PATTERN.matcher(word).matches()) { + if (LiteralEnum.LIST_PATTERN.matcher(word).matches()) { return TokenTypeEnum.LIST; } - if (MAP_PATTERN.matcher(word).matches()) { + if (LiteralEnum.MAP_PATTERN.matcher(word).matches()) { return TokenTypeEnum.MAP; } return null; -- Gitee From 163e86b2605c36f3f3f2e2622ce3f68ab33bff9d Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 17 Mar 2021 21:01:43 +0800 Subject: [PATCH 007/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/common/enums/LiteralEnum.java | 39 ++++++++ .../com/sum/spirit/common/enums/TypeEnum.java | 16 ++- .../sum/spirit/core/api/SemanticParser.java | 2 +- .../action/AbstractSemanticParser.java | 97 ++++++++----------- .../element/action/SemanticParserImpl.java | 4 +- .../com/sum/spirit/core/lexer/CoreLexer.java | 4 +- .../core/lexer/action/RegionAction.java | 2 +- 7 files changed, 100 insertions(+), 64 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/LiteralEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/LiteralEnum.java index 7787629e..188e63b4 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/LiteralEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/LiteralEnum.java @@ -13,4 +13,43 @@ public enum LiteralEnum { public static final Pattern STRING_PATTERN = Pattern.compile("^\"[\\s\\S]*\"$"); public static final Pattern LIST_PATTERN = Pattern.compile("^\\[[\\s\\S]*\\]$"); public static final Pattern MAP_PATTERN = Pattern.compile("^\\{[\\s\\S]*\\}$"); + + public static final Pattern VISIT_INDEX_PATTERN = Pattern.compile("^\\[\\d+\\]$"); + + public static boolean isNull(String word) { + return NULL_PATTERN.matcher(word).matches(); + } + + public static boolean isBoolean(String word) { + return BOOLEAN_PATTERN.matcher(word).matches(); + } + + public static boolean isChar(String word) { + return CHAR_PATTERN.matcher(word).matches(); + } + + public static boolean isInt(String word) { + return INT_PATTERN.matcher(word).matches(); + } + + public static boolean isLong(String word) { + return LONG_PATTERN.matcher(word).matches(); + } + + public static boolean isDouble(String word) { + return DOUBLE_PATTERN.matcher(word).matches(); + } + + public static boolean isString(String word) { + return STRING_PATTERN.matcher(word).matches(); + } + + public static boolean isList(String word) { + return !VISIT_INDEX_PATTERN.matcher(word).matches() && LiteralEnum.LIST_PATTERN.matcher(word).matches(); + } + + public static boolean isMap(String word) { + return MAP_PATTERN.matcher(word).matches(); + } + } diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java index ecf65f90..f00ad7aa 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java @@ -4,10 +4,20 @@ import java.util.regex.Pattern; public class TypeEnum { ; - public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); public static final Pattern TYPE_PATTERN = Pattern.compile("^[A-Z]+\\w*$"); + public static final Pattern TYPE_ARRAY_PATTERN = Pattern.compile("^[A-Z]+\\w*\\[\\]$"); + public static final Pattern GENERIC_TYPE_PATTERN = Pattern.compile("^[A-Z]+\\w*<[\\s\\S]+>$"); + + public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); - public static boolean isPureType(String prefix) { - return PrimitiveEnum.isPrimitiveBySimple(prefix) || (!CONST_VAR_PATTERN.matcher(prefix).matches() && TYPE_PATTERN.matcher(prefix).matches()); + public static boolean isTypePrefix(String word) { + return PrimitiveEnum.isPrimitiveBySimple(word) || (!CONST_VAR_PATTERN.matcher(word).matches() && TYPE_PATTERN.matcher(word).matches()); } + + public static boolean isType(String word) { + return !CONST_VAR_PATTERN.matcher(word).matches() + && (PrimitiveEnum.isPrimitiveBySimple(word) || PrimitiveEnum.isPrimitiveArrayBySimple(word) || TypeEnum.TYPE_PATTERN.matcher(word).matches() + || TypeEnum.TYPE_ARRAY_PATTERN.matcher(word).matches() || TypeEnum.GENERIC_TYPE_PATTERN.matcher(word).matches()); + } + } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java index 5fb7145a..235b9c4a 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java @@ -32,7 +32,7 @@ public interface SemanticParser { boolean isInit(String word); - boolean isValue(String word); + boolean isLiteral(String word); boolean isSubexpress(String word); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index 51a38da7..880ded36 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -9,6 +9,7 @@ import com.sum.spirit.common.enums.LiteralEnum; import com.sum.spirit.common.enums.PrimitiveEnum; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.TokenTypeEnum; +import com.sum.spirit.common.enums.TypeEnum; import com.sum.spirit.core.api.SemanticParser; import com.sum.spirit.core.element.entity.Token; @@ -17,10 +18,6 @@ public abstract class AbstractSemanticParser implements SemanticParser { public static final Pattern PATH_PATTERN = Pattern.compile("^(\\w+\\.)+\\w+$"); public static final Pattern ANNOTATION_PATTERN = Pattern.compile("^@[A-Z]+\\w+(\\([\\s\\S]+\\))?$"); - public static final Pattern TYPE_PATTERN = Pattern.compile("^[A-Z]+\\w*$"); - public static final Pattern TYPE_ARRAY_PATTERN = Pattern.compile("^[A-Z]+\\w*\\[\\]$"); - public static final Pattern GENERIC_TYPE_PATTERN = Pattern.compile("^[A-Z]+\\w*<[\\s\\S]+>$"); - public static final Pattern PRIMITIVE_ARRAY_INIT_PATTERN = Pattern.compile("^(" + PrimitiveEnum.PRIMITIVE_ENUM + ")\\[\\d+\\]$"); public static final Pattern PRIMITIVE_ARRAY_CERTAIN_INIT_PATTERN = Pattern.compile("^(" + PrimitiveEnum.PRIMITIVE_ENUM + ")\\[\\]\\{[\\s\\S]*\\}$"); public static final Pattern TYPE_ARRAY_INIT_PATTERN = Pattern.compile("^[A-Z]+\\w*\\[\\d+\\]$"); @@ -48,7 +45,7 @@ public abstract class AbstractSemanticParser implements SemanticParser { @Override public boolean isPath(String word) { - return !LiteralEnum.DOUBLE_PATTERN.matcher(word).matches() && PATH_PATTERN.matcher(word).matches(); + return !LiteralEnum.isDouble(word) && PATH_PATTERN.matcher(word).matches(); } @Override @@ -73,12 +70,7 @@ public abstract class AbstractSemanticParser implements SemanticParser { @Override public boolean isType(String word) { - return !CONST_VAR_PATTERN.matcher(word).matches() && // - (PrimitiveEnum.isPrimitiveBySimple(word) || // - PrimitiveEnum.isPrimitiveArrayBySimple(word) || // - TYPE_PATTERN.matcher(word).matches() || // - TYPE_ARRAY_PATTERN.matcher(word).matches() || // - GENERIC_TYPE_PATTERN.matcher(word).matches()); + return TypeEnum.isType(word); } @Override @@ -91,16 +83,10 @@ public abstract class AbstractSemanticParser implements SemanticParser { } @Override - public boolean isValue(String word) { - return LiteralEnum.NULL_PATTERN.matcher(word).matches() || // - LiteralEnum.BOOLEAN_PATTERN.matcher(word).matches() || // - LiteralEnum.CHAR_PATTERN.matcher(word).matches() || // - LiteralEnum.INT_PATTERN.matcher(word).matches() || // - LiteralEnum.LONG_PATTERN.matcher(word).matches() || // - LiteralEnum.DOUBLE_PATTERN.matcher(word).matches() || // - LiteralEnum.STRING_PATTERN.matcher(word).matches() || // - (!VISIT_INDEX_PATTERN.matcher(word).matches() && LiteralEnum.LIST_PATTERN.matcher(word).matches()) || // not be "[0]" - LiteralEnum.MAP_PATTERN.matcher(word).matches(); + public boolean isLiteral(String word) { + return LiteralEnum.isNull(word) || LiteralEnum.isBoolean(word) || LiteralEnum.isChar(word) || // + LiteralEnum.isInt(word) || LiteralEnum.isLong(word) || LiteralEnum.isDouble(word) || // + LiteralEnum.isString(word) || LiteralEnum.isList(word) || LiteralEnum.isMap(word); } @Override @@ -110,7 +96,7 @@ public abstract class AbstractSemanticParser implements SemanticParser { @Override public boolean isVariable(String word) { - return VAR_PATTERN.matcher(word).matches() || CONST_VAR_PATTERN.matcher(word).matches(); + return CONST_VAR_PATTERN.matcher(word).matches() || VAR_PATTERN.matcher(word).matches(); } @Override @@ -124,48 +110,48 @@ public abstract class AbstractSemanticParser implements SemanticParser { public TokenTypeEnum getInitTokenType(String word) { if (PRIMITIVE_ARRAY_INIT_PATTERN.matcher(word).matches()) { return TokenTypeEnum.ARRAY_INIT; - } - if (PRIMITIVE_ARRAY_CERTAIN_INIT_PATTERN.matcher(word).matches()) { + + } else if (PRIMITIVE_ARRAY_CERTAIN_INIT_PATTERN.matcher(word).matches()) { return TokenTypeEnum.ARRAY_INIT; - } - if (TYPE_ARRAY_INIT_PATTERN.matcher(word).matches()) { + + } else if (TYPE_ARRAY_INIT_PATTERN.matcher(word).matches()) { return TokenTypeEnum.ARRAY_INIT; - } - if (TYPE_ARRAY_CERTAIN_INIT_PATTERN.matcher(word).matches()) { + + } else if (TYPE_ARRAY_CERTAIN_INIT_PATTERN.matcher(word).matches()) { return TokenTypeEnum.ARRAY_INIT; - } - if (TYPE_INIT_PATTERN.matcher(word).matches()) { + + } else if (TYPE_INIT_PATTERN.matcher(word).matches()) { return TokenTypeEnum.TYPE_INIT; } return null; } - public TokenTypeEnum getValueTokenType(String word) { - if (LiteralEnum.NULL_PATTERN.matcher(word).matches()) { + public TokenTypeEnum getLiteralTokenType(String word) { + if (LiteralEnum.isNull(word)) { return TokenTypeEnum.NULL; - } - if (LiteralEnum.BOOLEAN_PATTERN.matcher(word).matches()) { + + } else if (LiteralEnum.isBoolean(word)) { return TokenTypeEnum.BOOL; - } - if (LiteralEnum.CHAR_PATTERN.matcher(word).matches()) { + + } else if (LiteralEnum.isChar(word)) { return TokenTypeEnum.CHAR; - } - if (LiteralEnum.INT_PATTERN.matcher(word).matches()) { + + } else if (LiteralEnum.isInt(word)) { return TokenTypeEnum.INT; - } - if (LiteralEnum.LONG_PATTERN.matcher(word).matches()) { + + } else if (LiteralEnum.isLong(word)) { return TokenTypeEnum.LONG; - } - if (LiteralEnum.DOUBLE_PATTERN.matcher(word).matches()) { + + } else if (LiteralEnum.isDouble(word)) { return TokenTypeEnum.DOUBLE; - } - if (LiteralEnum.STRING_PATTERN.matcher(word).matches()) { + + } else if (LiteralEnum.isString(word)) { return TokenTypeEnum.STRING; - } - if (LiteralEnum.LIST_PATTERN.matcher(word).matches()) { + + } else if (LiteralEnum.isList(word)) { return TokenTypeEnum.LIST; - } - if (LiteralEnum.MAP_PATTERN.matcher(word).matches()) { + + } else if (LiteralEnum.isMap(word)) { return TokenTypeEnum.MAP; } return null; @@ -174,21 +160,22 @@ public abstract class AbstractSemanticParser implements SemanticParser { public TokenTypeEnum getSubexpressTokenType(String word) { if (isType(getCastType(word))) { return TokenTypeEnum.CAST; + } else { + return TokenTypeEnum.SUBEXPRESS; } - return TokenTypeEnum.SUBEXPRESS; } public TokenTypeEnum getAccessTokenType(String word) { if (LOCAL_METHOD_PATTERN.matcher(word).matches()) { return TokenTypeEnum.LOCAL_METHOD; - } - if (VISIT_FIELD_PATTERN.matcher(word).matches()) { + + } else if (VISIT_FIELD_PATTERN.matcher(word).matches()) { return TokenTypeEnum.VISIT_FIELD; - } - if (VISIT_METHOD_PATTERN.matcher(word).matches()) { + + } else if (VISIT_METHOD_PATTERN.matcher(word).matches()) { return TokenTypeEnum.VISIT_METHOD; - } - if (VISIT_INDEX_PATTERN.matcher(word).matches()) { + + } else if (VISIT_INDEX_PATTERN.matcher(word).matches()) { return TokenTypeEnum.VISIT_INDEX; } return null; diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java index 8b47b307..3d00283e 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java @@ -50,8 +50,8 @@ public class SemanticParserImpl extends AbstractSemanticParser { } else if (isInit(word)) { token.tokenType = getInitTokenType(word); - } else if (isValue(word)) { - token.tokenType = getValueTokenType(word); + } else if (isLiteral(word)) { + token.tokenType = getLiteralTokenType(word); } else if (isSubexpress(word)) { token.tokenType = getSubexpressTokenType(word); diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java index 86179871..09756f3b 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java @@ -12,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; +import com.sum.spirit.common.enums.LiteralEnum; import com.sum.spirit.common.utils.LineUtils; import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.CharAction; @@ -29,7 +30,6 @@ import cn.hutool.core.lang.Assert; public class CoreLexer extends AbstractCharsHandler implements Lexer, InitializingBean { public static final Pattern TYPE_END_PATTERN = Pattern.compile("^[\\s\\S]+\\.[A-Z]+\\w+$"); - public static final Pattern DOUBLE_PATTERN = Pattern.compile("^\\d+\\.\\d+$"); public List actions; @Autowired @@ -81,7 +81,7 @@ public class CoreLexer extends AbstractCharsHandler implements Lexer, Initializi public void splitWords(List words) { for (int index = 0; index < words.size(); index++) {// 如果一个片段中,包含“.”,那么进行更细致的拆分 String word = words.get(index); - if (word.indexOf(".") > 0 && !TYPE_END_PATTERN.matcher(word).matches() && !DOUBLE_PATTERN.matcher(word).matches()) { + if (word.indexOf(".") > 0 && !LiteralEnum.isDouble(word) && !TYPE_END_PATTERN.matcher(word).matches()) { List subWords = Arrays.asList(word.replaceAll("\\.", " .").split(" ")); words.remove(index); words.addAll(index, subWords); diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java index 5f53f23d..e6ca4ed5 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java @@ -71,7 +71,7 @@ public class RegionAction extends AbstractLexerAction { } else if (ch == '[') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; // 前缀必须是类型才合并 - if (region0 != null && !TypeEnum.isPureType(subRegion(builder, region0))) { + if (region0 != null && !TypeEnum.isTypePrefix(subRegion(builder, region0))) { region0 = null; } Region region1 = findRegion(builder, context.index, '[', ']'); -- Gitee From efbf5c858bf973f9e1341ae801aa36f4ffc2a7aa Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 17 Mar 2021 21:18:02 +0800 Subject: [PATCH 008/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/sum/spirit/common/enums/TypeEnum.java | 6 +++++- .../src/main/java/com/sum/spirit/core/lexer/CoreLexer.java | 6 ++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java index f00ad7aa..478e0e05 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java @@ -7,8 +7,8 @@ public class TypeEnum { public static final Pattern TYPE_PATTERN = Pattern.compile("^[A-Z]+\\w*$"); public static final Pattern TYPE_ARRAY_PATTERN = Pattern.compile("^[A-Z]+\\w*\\[\\]$"); public static final Pattern GENERIC_TYPE_PATTERN = Pattern.compile("^[A-Z]+\\w*<[\\s\\S]+>$"); - public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); + public static final Pattern TYPE_END_PATTERN = Pattern.compile("^[\\s\\S]+\\.[A-Z]+\\w+$"); public static boolean isTypePrefix(String word) { return PrimitiveEnum.isPrimitiveBySimple(word) || (!CONST_VAR_PATTERN.matcher(word).matches() && TYPE_PATTERN.matcher(word).matches()); @@ -20,4 +20,8 @@ public class TypeEnum { || TypeEnum.TYPE_ARRAY_PATTERN.matcher(word).matches() || TypeEnum.GENERIC_TYPE_PATTERN.matcher(word).matches()); } + public static boolean isTypeEnd(String word) { + return TYPE_END_PATTERN.matcher(word).matches(); + } + } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java index 09756f3b..c55ef005 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.InitializingBean; @@ -13,6 +12,7 @@ import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.LiteralEnum; +import com.sum.spirit.common.enums.TypeEnum; import com.sum.spirit.common.utils.LineUtils; import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.CharAction; @@ -29,8 +29,6 @@ import cn.hutool.core.lang.Assert; @DependsOn("springUtils") public class CoreLexer extends AbstractCharsHandler implements Lexer, InitializingBean { - public static final Pattern TYPE_END_PATTERN = Pattern.compile("^[\\s\\S]+\\.[A-Z]+\\w+$"); - public List actions; @Autowired public BorderAction borderAction; @@ -81,7 +79,7 @@ public class CoreLexer extends AbstractCharsHandler implements Lexer, Initializi public void splitWords(List words) { for (int index = 0; index < words.size(); index++) {// 如果一个片段中,包含“.”,那么进行更细致的拆分 String word = words.get(index); - if (word.indexOf(".") > 0 && !LiteralEnum.isDouble(word) && !TYPE_END_PATTERN.matcher(word).matches()) { + if (word.indexOf(".") > 0 && !LiteralEnum.isDouble(word) && !TypeEnum.isTypeEnd(word)) { List subWords = Arrays.asList(word.replaceAll("\\.", " .").split(" ")); words.remove(index); words.addAll(index, subWords); -- Gitee From dc5509a9ec3df813cd045fc444c477cf39d9b40a Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 18 Mar 2021 10:28:31 +0800 Subject: [PATCH 009/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/common/enums/TokenTypeEnum.java | 2 +- .../com/sum/spirit/common/enums/TypeEnum.java | 63 ++++++++++++++++--- .../compile/deduce/InvocationVisiter.java | 2 +- .../core/compile/deduce/TypeFactory.java | 6 +- .../action/AbstractSemanticParser.java | 29 ++------- .../spirit/core/element/frame/Semantic.java | 10 +-- 6 files changed, 70 insertions(+), 42 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java index 811d7606..044c3533 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java @@ -10,7 +10,7 @@ public enum TokenTypeEnum { ARRAY_INIT, // 数组初始化 TYPE_INIT, // 类型初始化 NULL, // 空 - BOOL, // 布尔 + BOOLEAN, // 布尔 CHAR, // 字符 INT, // 整型 LONG, // 长整型 diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java index 478e0e05..2a34d4ac 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java @@ -2,26 +2,71 @@ package com.sum.spirit.common.enums; import java.util.regex.Pattern; -public class TypeEnum { +public enum TypeEnum { ; + public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); + public static final Pattern TYPE_END_PATTERN = Pattern.compile("^[\\s\\S]+\\.[A-Z]+\\w+$"); + public static final Pattern TYPE_PATTERN = Pattern.compile("^[A-Z]+\\w*$"); public static final Pattern TYPE_ARRAY_PATTERN = Pattern.compile("^[A-Z]+\\w*\\[\\]$"); public static final Pattern GENERIC_TYPE_PATTERN = Pattern.compile("^[A-Z]+\\w*<[\\s\\S]+>$"); - public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); - public static final Pattern TYPE_END_PATTERN = Pattern.compile("^[\\s\\S]+\\.[A-Z]+\\w+$"); + + public static final Pattern PRIMITIVE_ARRAY_SIZE_INIT_PATTERN = Pattern.compile("^(" + PrimitiveEnum.PRIMITIVE_ENUM + ")\\[\\d+\\]$"); + public static final Pattern PRIMITIVE_ARRAY_LITERAL_INIT_PATTERN = Pattern.compile("^(" + PrimitiveEnum.PRIMITIVE_ENUM + ")\\[\\]\\{[\\s\\S]*\\}$"); + public static final Pattern TYPE_ARRAY_SIZE_INIT_PATTERN = Pattern.compile("^[A-Z]+\\w*\\[\\d+\\]$"); + public static final Pattern TYPE_ARRAY_LITERAL_INIT_PATTERN = Pattern.compile("^[A-Z]+\\w*\\[\\]\\{[\\s\\S]*\\}$"); + public static final Pattern TYPE_INIT_PATTERN = Pattern.compile("^[A-Z]+\\w*(<[\\s\\S]+>)?\\([\\s\\S]*\\)$"); public static boolean isTypePrefix(String word) { - return PrimitiveEnum.isPrimitiveBySimple(word) || (!CONST_VAR_PATTERN.matcher(word).matches() && TYPE_PATTERN.matcher(word).matches()); + return PrimitiveEnum.isPrimitiveBySimple(word) || isType(word); + } + + public static boolean isTypeEnd(String word) { + return TYPE_END_PATTERN.matcher(word).matches(); } public static boolean isType(String word) { - return !CONST_VAR_PATTERN.matcher(word).matches() - && (PrimitiveEnum.isPrimitiveBySimple(word) || PrimitiveEnum.isPrimitiveArrayBySimple(word) || TypeEnum.TYPE_PATTERN.matcher(word).matches() - || TypeEnum.TYPE_ARRAY_PATTERN.matcher(word).matches() || TypeEnum.GENERIC_TYPE_PATTERN.matcher(word).matches()); + return !CONST_VAR_PATTERN.matcher(word).matches() && TYPE_PATTERN.matcher(word).matches(); } - public static boolean isTypeEnd(String word) { - return TYPE_END_PATTERN.matcher(word).matches(); + public static boolean isTypeArray(String word) { + return TYPE_ARRAY_PATTERN.matcher(word).matches(); + } + + public static boolean isGenericType(String word) { + return GENERIC_TYPE_PATTERN.matcher(word).matches(); + } + + public static boolean isPrimitiveArraySizeInit(String word) { + return PRIMITIVE_ARRAY_SIZE_INIT_PATTERN.matcher(word).matches(); + } + + public static boolean isPrimitiveArrayLiteralInit(String word) { + return PRIMITIVE_ARRAY_LITERAL_INIT_PATTERN.matcher(word).matches(); + } + + public static boolean isTypeArraySizeInit(String word) { + return TYPE_ARRAY_SIZE_INIT_PATTERN.matcher(word).matches(); + } + + public static boolean isTypeArrayLiteralInit(String word) { + return TYPE_ARRAY_LITERAL_INIT_PATTERN.matcher(word).matches(); + } + + public static boolean isTypeInit(String word) { + return TYPE_INIT_PATTERN.matcher(word).matches(); + } + + public static boolean isAnyType(String word) { + return !CONST_VAR_PATTERN.matcher(word).matches() && // + (PrimitiveEnum.isPrimitiveBySimple(word) || PrimitiveEnum.isPrimitiveArrayBySimple(word) || // + isType(word) || isTypeArray(word) || isGenericType(word)); + } + + public static boolean isAnyInit(String word) { + return isPrimitiveArraySizeInit(word) || isPrimitiveArrayLiteralInit(word) || // + isTypeArraySizeInit(word) || isTypeArrayLiteralInit(word) || // + isTypeInit(word); } } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java index f620fddb..17fe190a 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java @@ -35,7 +35,7 @@ public class InvocationVisiter { continue; } List parameterTypes = token.isInvoke() ? getParameterTypes(clazz, token) : null; - if (token.isType() || token.isArrayInit() || token.isTypeInit() || token.isCast() || token.isValue()) { + if (token.isType() || token.isArrayInit() || token.isTypeInit() || token.isCast() || token.isLiteral()) { token.setAttr(AttributeEnum.TYPE, factory.create(clazz, token)); } else if (token.isSubexpress()) { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactory.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactory.java index 81d206cd..8bb5a7ee 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactory.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactory.java @@ -56,7 +56,7 @@ public class TypeFactory extends AbstractTypeFactory { } else if (token.isAnnotation() || token.isArrayInit() || token.isTypeInit() || token.isCast()) { return create(clazz, (String) token.attr(AttributeEnum.SIMPLE_NAME)); - } else if (token.isValue()) {// 1, 1.1, "xxxx" + } else if (token.isLiteral()) {// 1, 1.1, "xxxx" return getValueType(clazz, token); } return null; @@ -95,7 +95,7 @@ public class TypeFactory extends AbstractTypeFactory { } public IType getValueType(IClass clazz, Token token) { - if (token.isBool()) { + if (token.isBoolean()) { return StaticTypes.BOOLEAN; } else if (token.isChar()) { return StaticTypes.CHAR; @@ -107,7 +107,7 @@ public class TypeFactory extends AbstractTypeFactory { return StaticTypes.DOUBLE; } else if (token.isNull()) { return StaticTypes.NULL; - } else if (token.isStr()) { + } else if (token.isString()) { return StaticTypes.STRING; } else if (token.isList()) { return getListType(clazz, token); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index 880ded36..ebe6a2a1 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -6,7 +6,6 @@ import java.util.regex.Pattern; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.enums.LiteralEnum; -import com.sum.spirit.common.enums.PrimitiveEnum; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.common.enums.TypeEnum; @@ -18,12 +17,6 @@ public abstract class AbstractSemanticParser implements SemanticParser { public static final Pattern PATH_PATTERN = Pattern.compile("^(\\w+\\.)+\\w+$"); public static final Pattern ANNOTATION_PATTERN = Pattern.compile("^@[A-Z]+\\w+(\\([\\s\\S]+\\))?$"); - public static final Pattern PRIMITIVE_ARRAY_INIT_PATTERN = Pattern.compile("^(" + PrimitiveEnum.PRIMITIVE_ENUM + ")\\[\\d+\\]$"); - public static final Pattern PRIMITIVE_ARRAY_CERTAIN_INIT_PATTERN = Pattern.compile("^(" + PrimitiveEnum.PRIMITIVE_ENUM + ")\\[\\]\\{[\\s\\S]*\\}$"); - public static final Pattern TYPE_ARRAY_INIT_PATTERN = Pattern.compile("^[A-Z]+\\w*\\[\\d+\\]$"); - public static final Pattern TYPE_ARRAY_CERTAIN_INIT_PATTERN = Pattern.compile("^[A-Z]+\\w*\\[\\]\\{[\\s\\S]*\\}$"); - public static final Pattern TYPE_INIT_PATTERN = Pattern.compile("^[A-Z]+\\w*(<[\\s\\S]+>)?\\([\\s\\S]*\\)$"); - public static final Pattern SUBEXPRESS_PATTERN = Pattern.compile("^\\([\\s\\S]+\\)$"); public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); public static final Pattern VAR_PATTERN = Pattern.compile("^[a-z]+\\w*$"); @@ -70,16 +63,12 @@ public abstract class AbstractSemanticParser implements SemanticParser { @Override public boolean isType(String word) { - return TypeEnum.isType(word); + return TypeEnum.isAnyType(word); } @Override public boolean isInit(String word) { - return PRIMITIVE_ARRAY_INIT_PATTERN.matcher(word).matches() || // - PRIMITIVE_ARRAY_CERTAIN_INIT_PATTERN.matcher(word).matches() || // - TYPE_ARRAY_INIT_PATTERN.matcher(word).matches() || // - TYPE_ARRAY_CERTAIN_INIT_PATTERN.matcher(word).matches() || // - TYPE_INIT_PATTERN.matcher(word).matches(); + return TypeEnum.isAnyInit(word); } @Override @@ -108,19 +97,13 @@ public abstract class AbstractSemanticParser implements SemanticParser { } public TokenTypeEnum getInitTokenType(String word) { - if (PRIMITIVE_ARRAY_INIT_PATTERN.matcher(word).matches()) { - return TokenTypeEnum.ARRAY_INIT; - - } else if (PRIMITIVE_ARRAY_CERTAIN_INIT_PATTERN.matcher(word).matches()) { - return TokenTypeEnum.ARRAY_INIT; - - } else if (TYPE_ARRAY_INIT_PATTERN.matcher(word).matches()) { + if (TypeEnum.isPrimitiveArraySizeInit(word) || TypeEnum.isPrimitiveArrayLiteralInit(word)) { return TokenTypeEnum.ARRAY_INIT; - } else if (TYPE_ARRAY_CERTAIN_INIT_PATTERN.matcher(word).matches()) { + } else if (TypeEnum.isTypeArraySizeInit(word) || TypeEnum.isTypeArrayLiteralInit(word)) { return TokenTypeEnum.ARRAY_INIT; - } else if (TYPE_INIT_PATTERN.matcher(word).matches()) { + } else if (TypeEnum.isTypeInit(word)) { return TokenTypeEnum.TYPE_INIT; } return null; @@ -131,7 +114,7 @@ public abstract class AbstractSemanticParser implements SemanticParser { return TokenTypeEnum.NULL; } else if (LiteralEnum.isBoolean(word)) { - return TokenTypeEnum.BOOL; + return TokenTypeEnum.BOOLEAN; } else if (LiteralEnum.isChar(word)) { return TokenTypeEnum.CHAR; diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java index c99fc151..6c57e59a 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java @@ -48,8 +48,8 @@ public abstract class Semantic extends AttributeMap { return tokenType == TokenTypeEnum.NULL; } - public boolean isBool() { - return tokenType == TokenTypeEnum.BOOL; + public boolean isBoolean() { + return tokenType == TokenTypeEnum.BOOLEAN; } public boolean isChar() { @@ -68,7 +68,7 @@ public abstract class Semantic extends AttributeMap { return tokenType == TokenTypeEnum.DOUBLE; } - public boolean isStr() { + public boolean isString() { return tokenType == TokenTypeEnum.STRING; } @@ -128,8 +128,8 @@ public abstract class Semantic extends AttributeMap { return isArrayInit() || isTypeInit(); } - public boolean isValue() { - return isNull() || isBool() || isChar() || isInt() || isLong() || isDouble() || isStr() || isList() || isMap(); + public boolean isLiteral() { + return isNull() || isBoolean() || isChar() || isInt() || isLong() || isDouble() || isString() || isList() || isMap(); } public boolean isNumber() { -- Gitee From f7e483472560ae81f7e19bc4e8c5fcae0575e540 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 18 Mar 2021 10:44:19 +0800 Subject: [PATCH 010/121] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/sum/spirit/core/api/ElementAction.java | 2 +- .../main/java/com/sum/spirit/core/compile/ElementVisiter.java | 2 +- .../sum/spirit/core/compile/action/AbstractElementAction.java | 2 +- .../spirit/core/compile/action/ElementExpressDeclarer.java | 4 ++-- .../sum/spirit/core/compile/action/ElementInvokeVisiter.java | 2 +- .../sum/spirit/core/compile/action/ElementTypeDeclarer.java | 4 ++-- .../spirit/core/compile/action/ElementVariableTracker.java | 2 +- .../src/main/java/com/sum/spirit/output/java/JavaBuilder.java | 2 +- .../spirit/output/java/action/AbstractTreeElementAction.java | 2 +- .../java/com/sum/spirit/output/java/action/CommonAction.java | 2 +- .../com/sum/spirit/output/java/action/SeparatorAction.java | 2 +- .../com/sum/spirit/output/java/action/StatementAction.java | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementAction.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementAction.java index aaf9557d..db7faead 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementAction.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementAction.java @@ -6,6 +6,6 @@ public interface ElementAction { boolean isTrigger(ElementEvent event); - void visit(ElementEvent event); + void handle(ElementEvent event); } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ElementVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ElementVisiter.java index 5245f3f3..ad975d89 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ElementVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ElementVisiter.java @@ -43,7 +43,7 @@ public class ElementVisiter implements InitializingBean { for (ElementAction action : actions) { ElementEvent event = new ElementEvent(clazz, element, context); if (action.isTrigger(event)) { - action.visit(event); + action.handle(event); } } return getVariableIfPossible(clazz, element); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractElementAction.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractElementAction.java index 7b4dc221..f265966f 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractElementAction.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractElementAction.java @@ -11,7 +11,7 @@ public abstract class AbstractElementAction implements ElementAction { } @Override - public void visit(ElementEvent event) { + public void handle(ElementEvent event) { if (!event.isMethodScope()) { visitFieldScope(event); } else { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java index 9d54d91f..e963860f 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java @@ -38,7 +38,7 @@ public class ElementExpressDeclarer extends AbstractElementAction { public TypeDerivator derivator; @Override - public void visit(ElementEvent event) { + public void handle(ElementEvent event) { IClass clazz = event.clazz; MethodContext context = event.context; Element element = event.element; @@ -57,7 +57,7 @@ public class ElementExpressDeclarer extends AbstractElementAction { } varToken.setAttr(AttributeEnum.TYPE, type); } - super.visit(event); + super.handle(event); } @Override diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementInvokeVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementInvokeVisiter.java index aaea7942..6547bfd8 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementInvokeVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementInvokeVisiter.java @@ -15,7 +15,7 @@ public class ElementInvokeVisiter extends AbstractElementAction { public InvocationVisiter visiter; @Override - public void visit(ElementEvent event) { + public void handle(ElementEvent event) { visiter.visit(event.clazz, event.element); } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java index 3c0893b5..0c09be3b 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java @@ -19,12 +19,12 @@ public class ElementTypeDeclarer extends AbstractElementAction { public TypeFactory factory; @Override - public void visit(ElementEvent event) { + public void handle(ElementEvent event) { Element element = event.element; if (element.isDeclare() || element.isDeclareAssign()) {// String text setTypeByTypeToken(event.clazz, element.get(0), element.get(1)); } - super.visit(event); + super.handle(event); } @Override diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementVariableTracker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementVariableTracker.java index 017d49bc..822371c0 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementVariableTracker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementVariableTracker.java @@ -15,7 +15,7 @@ public class ElementVariableTracker extends AbstractElementAction { public VariableTracker tracker; @Override - public void visit(ElementEvent event) { + public void handle(ElementEvent event) { tracker.visit(event.clazz, event.context, event.element); } diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java index 4d1e5006..e28e0bb8 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java @@ -148,7 +148,7 @@ public class JavaBuilder implements CodeBuilder, InitializingBean { for (ElementAction action : actions) { ElementEvent event = new ElementEvent(clazz, element); if (action.isTrigger(event)) { - action.visit(event); + action.handle(event); } } return element; diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java index 6bc4aae7..393369a6 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java @@ -28,7 +28,7 @@ public abstract class AbstractTreeElementAction extends AbstractElementAction { public SimpleDeducer deducer; @Override - public void visit(ElementEvent event) { + public void handle(ElementEvent event) { IClass clazz = event.clazz; Statement statement = event.element; StmtVisiter.visit(statement, stmt -> { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java index 822ed00f..84a07c24 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java @@ -23,7 +23,7 @@ public class CommonAction extends AbstractElementAction { public ImportManager manager; @Override - public void visit(ElementEvent event) { + public void handle(ElementEvent event) { IClass clazz = event.clazz; Statement statement = event.element; StmtVisiter.visit(statement, stmt -> { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java index 4b279f33..b2c24581 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java @@ -16,7 +16,7 @@ import com.sum.spirit.core.element.entity.Token; public class SeparatorAction extends AbstractElementAction { @Override - public void visit(ElementEvent event) { + public void handle(ElementEvent event) { IClass clazz = event.clazz; Element element = event.element; diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java index 8406af97..f55466f2 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java @@ -40,7 +40,7 @@ public class StatementAction extends AbstractElementAction { public ImportManager manager; @Override - public void visit(ElementEvent event) { + public void handle(ElementEvent event) { IClass clazz = event.clazz; Element element = event.element; -- Gitee From 16545dbbc40262b113da1d3f426ceb4b8ab18bc4 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 18 Mar 2021 11:06:55 +0800 Subject: [PATCH 011/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/element/ElementBuilderImpl.java | 2 +- .../spirit/core/element/entity/SyntaxTree.java | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java index a42042a4..6657a2c8 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java @@ -49,7 +49,7 @@ public class ElementBuilderImpl implements ElementBuilder { // 4.语句 Statement statement = new Statement(tokens); // 5.语法枚举 - SyntaxEnum syntax = SyntaxTree.getSyntax(tokens); + SyntaxEnum syntax = SyntaxTree.getSimpleSyntax(tokens); // 6.构建语法树 SyntaxTree syntaxTree = null; if (syntax == null) { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java index 9596fbd3..faab01f5 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java @@ -9,14 +9,13 @@ import com.sum.spirit.common.enums.SyntaxEnum; public class SyntaxTree { - public static final int START_INDEX = 0; public List nodes; public SyntaxTree(List nodes) { this.nodes = nodes; } - public static SyntaxEnum getSyntax(List tokens) { + public static SyntaxEnum getSimpleSyntax(List tokens) { Token first = tokens.get(0); // keyword if (KeywordEnum.isStruct(first.toString())) { @@ -61,7 +60,7 @@ public class SyntaxTree { public SyntaxEnum getLineSyntax() { - Node firstNode = nodes.get(START_INDEX); + Node firstNode = nodes.get(0); Token firstToken = firstNode.token; // 如果是行级别关键字,则直接返回语法枚举 @@ -78,7 +77,7 @@ public class SyntaxTree { return null; } - Node firstNode = nodes.get(START_INDEX); + Node firstNode = nodes.get(0); Token firstToken = firstNode.token; // 如果只有一个节点,可能是方法调用 @@ -122,7 +121,7 @@ public class SyntaxTree { return null; } - Node firstNode = nodes.get(START_INDEX); + Node firstNode = nodes.get(0); Token firstToken = firstNode.token; if (firstToken.isType()) { Token nextToken = firstNode.next.token; @@ -136,9 +135,9 @@ public class SyntaxTree { public SyntaxEnum getSyntaxByThreeNodes() { - Token firstToken = nodes.get(START_INDEX).token; - Token secondToken = nodes.get(START_INDEX + 1).token; - Token thirdToken = nodes.get(START_INDEX + 2).token; + Token firstToken = nodes.get(0).token; + Token secondToken = nodes.get(1).token; + Token thirdToken = nodes.get(2).token; if (KeywordEnum.FOR.value.equals(firstToken.toString())) { if (secondToken.isSubexpress()) { -- Gitee From 0cd2c13d24084ccece19ebcedf88da9966691edd Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 18 Mar 2021 13:03:04 +0800 Subject: [PATCH 012/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E6=B7=BB=E5=8A=A0=E6=B5=8B=E8=AF=95=E6=A1=88?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/common/enums/SyntaxEnum.java | 6 +- .../spirit/core/clazz/ClassResolverImpl.java | 4 +- .../sum/spirit/core/compile/ClassVisiter.java | 2 +- .../element/action/SemanticParserImpl.java | 1 - .../core/element/entity/SyntaxTree.java | 15 +-- .../spirit/core/element/frame/Syntactic.java | 4 +- .../spirit/core/lexer/test/ElementTest.java | 109 +++++++++++++++++- .../sum/spirit/output/java/JavaBuilder.java | 2 +- 8 files changed, 119 insertions(+), 24 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java index cf0a44e4..b8729320 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java @@ -6,14 +6,14 @@ public enum SyntaxEnum { INTERFACE, // interface ABSTRACT, // abstract CLASS, // class - FIELD_ASSIGN, // name = "chen" - FUNC_DECLARE, // String hello() { - FUNC, // func hello(){ SUPER, // super() THIS, // this() DECLARE, // String text DECLARE_ASSIGN, // String text = "hello" ASSIGN, // text= "hello" + DECLARE_FUNC, // String hello() { + FUNC, // func hello(){ + FIELD_ASSIGN, // var.text = "abc" INVOKE, // var1.invoke() RETURN, // return var1 IF, // if i > 100 { diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java index 8a128373..08fe2f9c 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java @@ -48,7 +48,7 @@ public class ClassResolverImpl implements ClassResolver { fields.add(new IField(annotations, element)); annotations.clear(); - } else if (element.isFuncDeclare() || element.isFunc()) { + } else if (element.isDeclareFunc() || element.isFunc()) { element.addModifier(KeywordEnum.STATIC.value).addModifier(KeywordEnum.PUBLIC.value); methods.add(new IMethod(annotations, element)); annotations.clear(); @@ -115,7 +115,7 @@ public class ClassResolverImpl implements ClassResolver { clazz.fields.add(new IField(annotations, element.addModifier(KeywordEnum.PUBLIC.value))); annotations.clear(); - } else if (element.isFuncDeclare() || element.isFunc()) { + } else if (element.isDeclareFunc() || element.isFunc()) { clazz.methods.add(new IMethod(annotations, element.addModifier(KeywordEnum.PUBLIC.value))); annotations.clear(); } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java index aa613d30..acc124a5 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java @@ -111,7 +111,7 @@ public class ClassVisiter { if (method.element.isFunc()) { return context.returnType != null ? context.returnType : StaticTypes.VOID; - } else if (method.element.isFuncDeclare()) { + } else if (method.element.isDeclareFunc()) { // 获取声明的类型 IType declaredType = factory.create(clazz, method.element.get(0)); // 如果这个方法有方法体 diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java index 3d00283e..27fbebf9 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java @@ -67,7 +67,6 @@ public class SemanticParserImpl extends AbstractSemanticParser { } public void setTokenValue(String word, Token token) { - if (token.isType()) { token.value = getStatement(word, true); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java index faab01f5..7c4172ef 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java @@ -34,45 +34,36 @@ public class SyntaxTree { } public SyntaxEnum getSyntax() { - SyntaxEnum syntax = getLineSyntax(); if (syntax != null) { return syntax; } - syntax = getSyntaxByOneNode(); if (syntax != null) { return syntax; } - syntax = getSyntaxByTwoNodes(); if (syntax != null) { return syntax; } - syntax = getSyntaxByThreeNodes(); if (syntax != null) { return syntax; } - throw new RuntimeException("Unknown syntax!"); } public SyntaxEnum getLineSyntax() { - Node firstNode = nodes.get(0); Token firstToken = firstNode.token; - // 如果是行级别关键字,则直接返回语法枚举 if (!firstNode.canSplit() && KeywordEnum.isLine(firstToken.toString())) { return SyntaxEnum.valueOf(firstToken.toString().toUpperCase()); } - return null; } public SyntaxEnum getSyntaxByOneNode() { - if (nodes.size() != 1) { return null; } @@ -97,7 +88,7 @@ public class SyntaxTree { if (nextToken.isVariable()) { // String text return SyntaxEnum.DECLARE; } else if (nextToken.isLocalMethod()) { // String test() - return SyntaxEnum.FUNC_DECLARE; + return SyntaxEnum.DECLARE_FUNC; } } else if (firstToken.isAssign()) { Token prevToken = firstNode.prev.token; @@ -116,7 +107,6 @@ public class SyntaxTree { } public SyntaxEnum getSyntaxByTwoNodes() { - if (nodes.size() != 2) { return null; } @@ -126,7 +116,7 @@ public class SyntaxTree { if (firstToken.isType()) { Token nextToken = firstNode.next.token; if (nextToken.isLocalMethod()) { - return SyntaxEnum.FUNC_DECLARE; + return SyntaxEnum.DECLARE_FUNC; } } @@ -134,7 +124,6 @@ public class SyntaxTree { } public SyntaxEnum getSyntaxByThreeNodes() { - Token firstToken = nodes.get(0).token; Token secondToken = nodes.get(1).token; Token thirdToken = nodes.get(2).token; diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java index 6ddf890a..788b6162 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java @@ -39,8 +39,8 @@ public abstract class Syntactic extends Statement { return syntax == SyntaxEnum.FIELD_ASSIGN; } - public boolean isFuncDeclare() { - return syntax == SyntaxEnum.FUNC_DECLARE; + public boolean isDeclareFunc() { + return syntax == SyntaxEnum.DECLARE_FUNC; } public boolean isFunc() { diff --git a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java index 08ebb764..5bab6785 100644 --- a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java +++ b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java @@ -1,11 +1,17 @@ package com.sum.spirit.core.lexer.test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.api.ElementBuilder; +import com.sum.spirit.core.element.entity.Element; +import com.sum.spirit.core.element.entity.Token; @SpringBootTest @DisplayName("语法分析器测试") @@ -14,10 +20,111 @@ public class ElementTest { @Autowired public ElementBuilder builder; + public static void assertTypeAndValue(Token token, TokenTypeEnum tokenTypeEnum, String value) { + assertEquals(token.tokenType, tokenTypeEnum); + assertEquals(token.toString(), value); + } + @Test - @DisplayName("方法声明") + @DisplayName("引入类型") public void test0000() { + String text = "import com.sum.test.Service"; + Element element = builder.build(text); + assertTrue(element.isImport()); + assertTrue(element.size() == 2); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "import"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.PATH, "com.sum.test.Service"); + } + + @Test + @DisplayName("注释") + public void test0001() { + String text = "@Service(name=\"test\")"; + Element element = builder.build(text); + assertTrue(element.isAnnotation()); + assertTrue(element.size() == 1); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.ANNOTATION, "@Service(name=\"test\")"); + } + + @Test + @DisplayName("声明接口") + public void test0002() { + String text = "interface Service {"; + Element element = builder.build(text); + assertTrue(element.isInterface()); + assertTrue(element.size() == 3); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "interface"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "Service"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + @Test + @DisplayName("声明抽象类型") + public void test0003() { + String text = "abstract Service {"; + Element element = builder.build(text); + assertTrue(element.isAbstract()); + assertTrue(element.size() == 3); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "abstract"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "Service"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("声明类型") + public void test0004() { + String text = "class Service {"; + Element element = builder.build(text); + assertTrue(element.isClass()); + assertTrue(element.size() == 3); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "class"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "Service"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("声明字段") + public void test0005() { + String text = "field = \"test\""; + Element element = builder.build(text); + assertTrue(element.isAssign()); + assertTrue(element.size() == 3); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "field"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.OPERATOR, "="); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"test\""); + } + + @Test + @DisplayName("声明类型字段") + public void test0006() { + String text = "String field = \"test\""; + Element element = builder.build(text); + assertTrue(element.isDeclareAssign()); + assertTrue(element.size() == 4); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "String"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "field"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.OPERATOR, "="); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"test\""); + } + + @Test + @DisplayName("声明方法") + public void test0007() { + String text = "func test(String arg0){"; + Element element = builder.build(text); + assertTrue(element.isFunc()); + assertTrue(element.size() == 3); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "func"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.LOCAL_METHOD, "test(String arg0)"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); } } diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java index e28e0bb8..00eb5d9e 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java @@ -105,7 +105,7 @@ public class JavaBuilder implements CodeBuilder, InitializingBean { } else {// public User() // public static synchronized String methodName() // 替换关键字 element.replaceModifier(KeywordEnum.SYNCH.value, JavaBuilder.SYNCHRONIZED_KEYWORD); - if (element.isFuncDeclare()) { + if (element.isDeclareFunc()) { // 抽象类型的没有方法体的方法,需要加上abstract关键字 if (clazz.isAbstract() && !method.isStatic() && !element.hasChild()) { element.insertModifier(KeywordEnum.PUBLIC.value, KeywordEnum.ABSTRACT.value); -- Gitee From f280f0122e3ef2468c0ce4e1cf9ad47d7b0e0882 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 18 Mar 2021 15:11:24 +0800 Subject: [PATCH 013/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AF=8D=E6=B3=95?= =?UTF-8?q?=E5=92=8C=E8=AF=AD=E6=B3=95=E7=9A=84=E8=AF=B4=E6=98=8E=E6=A1=88?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/common/enums/SyntaxEnum.java | 50 +++++++++------ .../spirit/common/enums/TokenTypeEnum.java | 64 +++++++++++-------- 2 files changed, 65 insertions(+), 49 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java index b8729320..875338c1 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java @@ -1,36 +1,44 @@ package com.sum.spirit.common.enums; +//import com.sum.spirit.example.Animal +//@Animal +//class Horse { +// name = "Jessie" +// func call() { +// return "I am Jessie!" +// } +//} public enum SyntaxEnum { - IMPORT, // import - ANNOTATION, // @Annotation - INTERFACE, // interface - ABSTRACT, // abstract - CLASS, // class + IMPORT, // import com.sum.spirit.example.Animal + ANNOTATION, // @Animal + INTERFACE, // interface Horse { + ABSTRACT, // abstract Horse { + CLASS, // class Horse { SUPER, // super() THIS, // this() - DECLARE, // String text - DECLARE_ASSIGN, // String text = "hello" - ASSIGN, // text= "hello" - DECLARE_FUNC, // String hello() { - FUNC, // func hello(){ - FIELD_ASSIGN, // var.text = "abc" - INVOKE, // var1.invoke() - RETURN, // return var1 - IF, // if i > 100 { - ELSE_IF, // else if i < 100 { + DECLARE, // String name + DECLARE_ASSIGN, // String name = "Jessie" + ASSIGN, // name = "Jessie" + DECLARE_FUNC, // String call() { + FUNC, // func call() { + FIELD_ASSIGN, // horse.name = "Jessie" + INVOKE, // horse.call() + RETURN, // return "I am Jessie!" + IF, // if i > 0 { + ELSE_IF, // else if i < 0 { ELSE, // else { END, // } - FOR, // for + FOR, // for (i=0; i<100; i++) { FOR_IN, // for item in list { - WHILE, // while i > 100 { + WHILE, // while i > 0 { CONTINUE, // continue BREAK, // break TRY, // try { CATCH, // catch Exception e { FINALLY, // finally { THROW, // throw RuntimeException(e) - SYNC, // sync - PRINT, // print - DEBUG, // debug - ERROR // error + SYNC, // sync horse { + PRINT, // print "Jessie" + DEBUG, // debug "Jessie" + ERROR // error "Jessie" } diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java index 044c3533..de6e9906 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java @@ -1,32 +1,40 @@ package com.sum.spirit.common.enums; +//import com.sum.spirit.example.Animal +//@Animal +//class Horse { +// name = "Jessie" +// func call() { +// return "I am Jessie!" +// } +//} public enum TokenTypeEnum { - PATH, // 类访问全路径 - ANNOTATION, // 注解 - KEYWORD, // 关键字 - OPERATOR, // 操作符 - SEPARATOR, // 分隔符 - TYPE, // 类型声明 - ARRAY_INIT, // 数组初始化 - TYPE_INIT, // 类型初始化 - NULL, // 空 - BOOLEAN, // 布尔 - CHAR, // 字符 - INT, // 整型 - LONG, // 长整型 - DOUBLE, // 双精度浮点数 - STRING, // 字符串 - LIST, // 数组集合 - MAP, // 映射集合 - SUBEXPRESS, // 子表达式 - CAST, // 类型强制转换 - VARIABLE, // 变量 - LOCAL_METHOD, // 本地方法 - VISIT_FIELD, // 访问字段 - VISIT_METHOD, // 调用方法 - VISIT_INDEX, // 访问数组 - PREFIX, // 前缀 - CUSTOM_PREFIX, // 自定义前缀 - CUSTOM_SUFFIX, // 自定义后缀 - CUSTOM_EXPRESS // 自定义表达式 + PATH, // com.sum.spirit.example.Animal + ANNOTATION, // @Animal + KEYWORD, // class + OPERATOR, // = + SEPARATOR, // { + TYPE, // Horse + ARRAY_INIT, // Horse[] + TYPE_INIT, // Horse() + NULL, // null + BOOLEAN, // true + CHAR, // 'c' + INT, // 0 + LONG, // 0L + DOUBLE, // 0.0 + STRING, // "Jessie" + LIST, // ["Jessie"] + MAP, // {"Jessie" : 0} + SUBEXPRESS, // (x + y) + CAST, // (Horse) + VARIABLE, // name + LOCAL_METHOD, // call() + VISIT_FIELD, // .name + VISIT_METHOD, // .call() + VISIT_INDEX, // [0] + PREFIX, // .call in .call() + CUSTOM_PREFIX, // user defined + CUSTOM_SUFFIX, // user defined + CUSTOM_EXPRESS // user defined } -- Gitee From e08c139deb6a09e13c56743eaa357d70bbca3669 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 18 Mar 2021 20:14:38 +0800 Subject: [PATCH 014/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E7=9A=84=E6=B5=8B=E8=AF=95=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/common/enums/SyntaxEnum.java | 12 +- .../spirit/core/lexer/test/ElementTest.java | 367 ++++++++++++++++-- 2 files changed, 343 insertions(+), 36 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java index 875338c1..92c63fdf 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java @@ -24,18 +24,18 @@ public enum SyntaxEnum { FIELD_ASSIGN, // horse.name = "Jessie" INVOKE, // horse.call() RETURN, // return "I am Jessie!" - IF, // if i > 0 { - ELSE_IF, // else if i < 0 { - ELSE, // else { + IF, // if name == "Jessie" { + ELSE_IF, // } else if name == "Jessie" { + ELSE, // } else { END, // } FOR, // for (i=0; i<100; i++) { FOR_IN, // for item in list { - WHILE, // while i > 0 { + WHILE, // while name == "Jessie" { CONTINUE, // continue BREAK, // break TRY, // try { - CATCH, // catch Exception e { - FINALLY, // finally { + CATCH, // } catch Exception e { + FINALLY, // } finally { THROW, // throw RuntimeException(e) SYNC, // sync horse { PRINT, // print "Jessie" diff --git a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java index 5bab6785..0fbb817d 100644 --- a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java +++ b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java @@ -26,105 +26,412 @@ public class ElementTest { } @Test - @DisplayName("引入类型") + @DisplayName("IMPORT") public void test0000() { - String text = "import com.sum.test.Service"; + String text = "import com.sum.spirit.example.Animal"; Element element = builder.build(text); assertTrue(element.isImport()); assertTrue(element.size() == 2); int count = 0; assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "import"); - assertTypeAndValue(element.get(count++), TokenTypeEnum.PATH, "com.sum.test.Service"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.PATH, "com.sum.spirit.example.Animal"); } @Test - @DisplayName("注释") + @DisplayName("ANNOTATION") public void test0001() { - String text = "@Service(name=\"test\")"; + String text = "@Animal"; Element element = builder.build(text); assertTrue(element.isAnnotation()); assertTrue(element.size() == 1); int count = 0; - assertTypeAndValue(element.get(count++), TokenTypeEnum.ANNOTATION, "@Service(name=\"test\")"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.ANNOTATION, "@Animal"); } @Test - @DisplayName("声明接口") + @DisplayName("INTERFACE") public void test0002() { - String text = "interface Service {"; + String text = "interface Horse {"; Element element = builder.build(text); assertTrue(element.isInterface()); assertTrue(element.size() == 3); int count = 0; assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "interface"); - assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "Service"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "Horse"); assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); } @Test - @DisplayName("声明抽象类型") + @DisplayName("ABSTRACT") public void test0003() { - String text = "abstract Service {"; + String text = "abstract Horse {"; Element element = builder.build(text); assertTrue(element.isAbstract()); assertTrue(element.size() == 3); int count = 0; assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "abstract"); - assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "Service"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "Horse"); assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); } @Test - @DisplayName("声明类型") + @DisplayName("CLASS") public void test0004() { - String text = "class Service {"; + String text = "class Horse {"; Element element = builder.build(text); assertTrue(element.isClass()); assertTrue(element.size() == 3); int count = 0; assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "class"); - assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "Service"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "Horse"); assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); } @Test - @DisplayName("声明字段") + @DisplayName("SUPER") public void test0005() { - String text = "field = \"test\""; + String text = "super()"; Element element = builder.build(text); - assertTrue(element.isAssign()); - assertTrue(element.size() == 3); + assertTrue(element.isSuper()); + assertTrue(element.size() == 1); int count = 0; - assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "field"); - assertTypeAndValue(element.get(count++), TokenTypeEnum.OPERATOR, "="); - assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"test\""); + assertTypeAndValue(element.get(count++), TokenTypeEnum.LOCAL_METHOD, "super()"); } @Test - @DisplayName("声明类型字段") + @DisplayName("THIS") public void test0006() { - String text = "String field = \"test\""; + String text = "this()"; + Element element = builder.build(text); + assertTrue(element.isThis()); + assertTrue(element.size() == 1); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.LOCAL_METHOD, "this()"); + } + + @Test + @DisplayName("DECLARE") + public void test0007() { + String text = "String name"; + Element element = builder.build(text); + assertTrue(element.isDeclare()); + assertTrue(element.size() == 2); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "String"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "name"); + } + + @Test + @DisplayName("DECLARE_ASSIGN") + public void test0008() { + String text = "String name = \"Jessie\""; Element element = builder.build(text); assertTrue(element.isDeclareAssign()); assertTrue(element.size() == 4); int count = 0; assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "String"); - assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "field"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "name"); assertTypeAndValue(element.get(count++), TokenTypeEnum.OPERATOR, "="); - assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"test\""); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"Jessie\""); } @Test - @DisplayName("声明方法") - public void test0007() { - String text = "func test(String arg0){"; + @DisplayName("ASSIGN") + public void test0009() { + String text = "name = \"Jessie\""; + Element element = builder.build(text); + assertTrue(element.isAssign()); + assertTrue(element.size() == 3); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "name"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.OPERATOR, "="); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"Jessie\""); + } + + @Test + @DisplayName("DECLARE_FUNC") + public void test0010() { + String text = "String call() {"; + Element element = builder.build(text); + assertTrue(element.isDeclareFunc()); + assertTrue(element.size() == 3); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "String"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.LOCAL_METHOD, "call()"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("FUNC") + public void test0011() { + String text = "func call() {"; Element element = builder.build(text); assertTrue(element.isFunc()); assertTrue(element.size() == 3); int count = 0; assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "func"); - assertTypeAndValue(element.get(count++), TokenTypeEnum.LOCAL_METHOD, "test(String arg0)"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.LOCAL_METHOD, "call()"); assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); } + @Test + @DisplayName("FIELD_ASSIGN") + public void test0012() { + String text = "horse.name = \"Jessie\""; + Element element = builder.build(text); + assertTrue(element.isFieldAssign()); + assertTrue(element.size() == 4); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "horse"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VISIT_FIELD, ".name"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.OPERATOR, "="); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"Jessie\""); + } + + @Test + @DisplayName("INVOKE") + public void test0013() { + String text = "horse.call()"; + Element element = builder.build(text); + assertTrue(element.isInvoke()); + assertTrue(element.size() == 2); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "horse"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VISIT_METHOD, ".call()"); + } + + @Test + @DisplayName("RETURN") + public void test0014() { + String text = "return \"I am Jessie!\""; + Element element = builder.build(text); + assertTrue(element.isReturn()); + assertTrue(element.size() == 2); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "return"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"I am Jessie!\""); + } + + @Test + @DisplayName("IF") + public void test0015() { + String text = "if name == \"Jessie\" {"; + Element element = builder.build(text); + assertTrue(element.isIf()); + assertTrue(element.size() == 5); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "if"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "name"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.OPERATOR, "=="); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"Jessie\""); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("ELSE_IF") + public void test0016() { + String text = "} else if name == \"Jessie\" {"; + Element element = builder.build(text); + assertTrue(element.isElseIf()); + assertTrue(element.size() == 7); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "}"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "else"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "if"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "name"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.OPERATOR, "=="); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"Jessie\""); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("ELSE") + public void test0017() { + String text = "} else {"; + Element element = builder.build(text); + assertTrue(element.isElse()); + assertTrue(element.size() == 3); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "}"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "else"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("END") + public void test0018() { + String text = "}"; + Element element = builder.build(text); + assertTrue(element.isEnd()); + assertTrue(element.size() == 1); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "}"); + } + + @Test + @DisplayName("FOR") + public void test0019() { + String text = "for (i=0; i<100; i++) {"; + Element element = builder.build(text); + assertTrue(element.isFor()); + assertTrue(element.size() == 3); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "for"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SUBEXPRESS, "(i = 0; i < 100; i++)"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("FOR_IN") + public void test0020() { + String text = "for item in list {"; + Element element = builder.build(text); + assertTrue(element.isForIn()); + assertTrue(element.size() == 5); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "for"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "item"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "in"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "list"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("WHILE") + public void test0021() { + String text = "while name == \"Jessie\" {"; + Element element = builder.build(text); + assertTrue(element.isWhile()); + assertTrue(element.size() == 5); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "while"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "name"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.OPERATOR, "=="); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"Jessie\""); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("CONTINUE") + public void test0022() { + String text = "continue"; + Element element = builder.build(text); + assertTrue(element.isContinue()); + assertTrue(element.size() == 1); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "continue"); + } + + @Test + @DisplayName("BREAK") + public void test0023() { + String text = "break"; + Element element = builder.build(text); + assertTrue(element.isBreak()); + assertTrue(element.size() == 1); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "break"); + } + + @Test + @DisplayName("TRY") + public void test0024() { + String text = "try {"; + Element element = builder.build(text); + assertTrue(element.isTry()); + assertTrue(element.size() == 2); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "try"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("CATCH") + public void test0025() { + String text = "} catch Exception e {"; + Element element = builder.build(text); + assertTrue(element.isCatch()); + assertTrue(element.size() == 5); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "}"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "catch"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "Exception"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "e"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("FINALLY") + public void test0026() { + String text = "} finally {"; + Element element = builder.build(text); + assertTrue(element.isFinally()); + assertTrue(element.size() == 3); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "}"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "finally"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("THROW") + public void test0027() { + String text = "throw RuntimeException(e)"; + Element element = builder.build(text); + assertTrue(element.isThrow()); + assertTrue(element.size() == 2); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "throw"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE_INIT, "RuntimeException(e)"); + } + + @Test + @DisplayName("SYNC") + public void test0028() { + String text = "sync horse {"; + Element element = builder.build(text); + assertTrue(element.isSync()); + assertTrue(element.size() == 3); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "sync"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.VARIABLE, "horse"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); + } + + @Test + @DisplayName("PRINT") + public void test0029() { + String text = "print \"Jessie\""; + Element element = builder.build(text); + assertTrue(element.isPrint()); + assertTrue(element.size() == 2); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "print"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"Jessie\""); + } + + @Test + @DisplayName("DEBUG") + public void test0030() { + String text = "debug \"Jessie\""; + Element element = builder.build(text); + assertTrue(element.isDebug()); + assertTrue(element.size() == 2); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "debug"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"Jessie\""); + } + + @Test + @DisplayName("ERROR") + public void test0031() { + String text = "error \"Jessie\""; + Element element = builder.build(text); + assertTrue(element.isError()); + assertTrue(element.size() == 2); + int count = 0; + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "error"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.STRING, "\"Jessie\""); + } + } -- Gitee From a92985bc0d349f27f5f4179207af7bc74c2e6ae3 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 19 Mar 2021 10:29:33 +0800 Subject: [PATCH 015/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/common/enums/TokenTypeEnum.java | 2 +- .../spirit/core/element/frame/Semantic.java | 4 + .../spirit/core/lexer/test/ElementTest.java | 2 +- .../spirit/core/lexer/test/SemanticTest.java | 222 ++++++++++++++++++ .../sum/spirit/core/lexer/test/LexerTest.java | 2 +- 5 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SemanticTest.java diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java index de6e9906..07f8a4da 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java @@ -15,7 +15,7 @@ public enum TokenTypeEnum { OPERATOR, // = SEPARATOR, // { TYPE, // Horse - ARRAY_INIT, // Horse[] + ARRAY_INIT, // Horse[1] TYPE_INIT, // Horse() NULL, // null BOOLEAN, // true diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java index 6c57e59a..fbc91617 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java @@ -16,6 +16,10 @@ public abstract class Semantic extends AttributeMap { this.tokenType = tokenType; } + public boolean isPath() { + return tokenType == TokenTypeEnum.PATH; + } + public boolean isAnnotation() { return tokenType == TokenTypeEnum.ANNOTATION; } diff --git a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java index 0fbb817d..1fb4e3dc 100644 --- a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java +++ b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java @@ -14,7 +14,7 @@ import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Token; @SpringBootTest -@DisplayName("语法分析器测试") +@DisplayName("语法测试") public class ElementTest { @Autowired diff --git a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SemanticTest.java b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SemanticTest.java new file mode 100644 index 00000000..0c2dad14 --- /dev/null +++ b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SemanticTest.java @@ -0,0 +1,222 @@ +package com.sum.spirit.core.lexer.test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.sum.spirit.core.api.SemanticParser; +import com.sum.spirit.core.element.entity.Statement; +import com.sum.spirit.core.element.entity.Token; + +@SpringBootTest +@DisplayName("语义测试") +public class SemanticTest { + + @Autowired + public SemanticParser parser; + + @Test + @DisplayName("PATH") + public void test0000() { + String text = "com.sum.spirit.example.Animal"; + Token token = parser.getToken(text); + assertTrue(token.isPath()); + } + + @Test + @DisplayName("ANNOTATION") + public void test0001() { + String text = "@Animal"; + Token token = parser.getToken(text); + assertTrue(token.isAnnotation()); + } + + @Test + @DisplayName("KEYWORD") + public void test0002() { + String text = "class"; + Token token = parser.getToken(text); + assertTrue(token.isKeyword()); + } + + @Test + @DisplayName("OPERATOR") + public void test0003() { + String text = "="; + Token token = parser.getToken(text); + assertTrue(token.isOperator()); + } + + @Test + @DisplayName("SEPARATOR") + public void test0004() { + String text = "{"; + Token token = parser.getToken(text); + assertTrue(token.isSeparator()); + } + + @Test + @DisplayName("TYPE") + public void test0005() { + String text = "Horse"; + Token token = parser.getToken(text); + assertTrue(token.isType()); + } + + @Test + @DisplayName("ARRAY_INIT") + public void test0006() { + String text = "Horse[1]"; + Token token = parser.getToken(text); + assertTrue(token.isArrayInit()); + } + + @Test + @DisplayName("TYPE_INIT") + public void test0007() { + String text = "Horse()"; + Token token = parser.getToken(text); + assertTrue(token.isTypeInit()); + } + + @Test + @DisplayName("NULL") + public void test0008() { + String text = "null"; + Token token = parser.getToken(text); + assertTrue(token.isNull()); + } + + @Test + @DisplayName("BOOLEAN") + public void test0009() { + String text = "true"; + Token token = parser.getToken(text); + assertTrue(token.isBoolean()); + } + + @Test + @DisplayName("CHAR") + public void test0010() { + String text = "'c'"; + Token token = parser.getToken(text); + assertTrue(token.isChar()); + } + + @Test + @DisplayName("INT") + public void test0011() { + String text = "0"; + Token token = parser.getToken(text); + assertTrue(token.isInt()); + } + + @Test + @DisplayName("LONG") + public void test0012() { + String text = "0L"; + Token token = parser.getToken(text); + assertTrue(token.isLong()); + } + + @Test + @DisplayName("DOUBLE") + public void test0013() { + String text = "0.0"; + Token token = parser.getToken(text); + assertTrue(token.isDouble()); + } + + @Test + @DisplayName("STRING") + public void test0014() { + String text = "\"Jessie\""; + Token token = parser.getToken(text); + assertTrue(token.isString()); + } + + @Test + @DisplayName("LIST") + public void test0015() { + String text = "[\"Jessie\"]"; + Token token = parser.getToken(text); + assertTrue(token.isList()); + } + + @Test + @DisplayName("MAP") + public void test0016() { + String text = "{\"Jessie\" : 0}"; + Token token = parser.getToken(text); + assertTrue(token.isMap()); + } + + @Test + @DisplayName("SUBEXPRESS") + public void test0017() { + String text = "(x + y)"; + Token token = parser.getToken(text); + assertTrue(token.isSubexpress()); + } + + @Test + @DisplayName("CAST") + public void test0018() { + String text = "(Horse)"; + Token token = parser.getToken(text); + assertTrue(token.isCast()); + } + + @Test + @DisplayName("VARIABLE") + public void test0019() { + String text = "name"; + Token token = parser.getToken(text); + assertTrue(token.isVariable()); + } + + @Test + @DisplayName("LOCAL_METHOD") + public void test0020() { + String text = "call()"; + Token token = parser.getToken(text); + assertTrue(token.isLocalMethod()); + } + + @Test + @DisplayName("VISIT_FIELD") + public void test0021() { + String text = ".name"; + Token token = parser.getToken(text); + assertTrue(token.isVisitField()); + } + + @Test + @DisplayName("VISIT_METHOD") + public void test0022() { + String text = ".call()"; + Token token = parser.getToken(text); + assertTrue(token.isVisitMethod()); + } + + @Test + @DisplayName("VISIT_INDEX") + public void test0023() { + String text = "[0]"; + Token token = parser.getToken(text); + assertTrue(token.isVisitIndex()); + } + + @Test + @DisplayName("PREFIX") + public void test0024() { + String text = ".call()"; + Token token = parser.getToken(text); + Statement statement = token.getValue(); + assertTrue(statement.get(0).isPrefix()); + } + +} diff --git a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java index deaf2fa3..b0d02908 100644 --- a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java +++ b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java @@ -16,7 +16,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j @SpringBootTest -@DisplayName("词法分析器测试") +@DisplayName("词法测试") public class LexerTest { @Autowired -- Gitee From 41ba4793d2c248d3325692628d18282e887750f6 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 19 Mar 2021 11:15:59 +0800 Subject: [PATCH 016/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E6=B7=BB=E5=8A=A0=E6=B5=8B=E8=AF=95=E6=A1=88?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/element/frame/Syntactic.java | 24 +++++++++---------- .../{ElementTest.java => SyntaxTest.java} | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) rename spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/{ElementTest.java => SyntaxTest.java} (99%) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java index 788b6162..6ab1c2fd 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java @@ -35,18 +35,6 @@ public abstract class Syntactic extends Statement { return syntax == SyntaxEnum.CLASS; } - public boolean isFieldAssign() { - return syntax == SyntaxEnum.FIELD_ASSIGN; - } - - public boolean isDeclareFunc() { - return syntax == SyntaxEnum.DECLARE_FUNC; - } - - public boolean isFunc() { - return syntax == SyntaxEnum.FUNC; - } - public boolean isSuper() { return syntax == SyntaxEnum.SUPER; } @@ -67,6 +55,18 @@ public abstract class Syntactic extends Statement { return syntax == SyntaxEnum.ASSIGN; } + public boolean isDeclareFunc() { + return syntax == SyntaxEnum.DECLARE_FUNC; + } + + public boolean isFunc() { + return syntax == SyntaxEnum.FUNC; + } + + public boolean isFieldAssign() { + return syntax == SyntaxEnum.FIELD_ASSIGN; + } + public boolean isInvoke() { return syntax == SyntaxEnum.INVOKE; } diff --git a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SyntaxTest.java similarity index 99% rename from spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java rename to spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SyntaxTest.java index 1fb4e3dc..04e9a75e 100644 --- a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/ElementTest.java +++ b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SyntaxTest.java @@ -15,7 +15,7 @@ import com.sum.spirit.core.element.entity.Token; @SpringBootTest @DisplayName("语法测试") -public class ElementTest { +public class SyntaxTest { @Autowired public ElementBuilder builder; -- Gitee From eb5f62afe4f3cff682df0d35e60a8cd62e86eb69 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 19 Mar 2021 13:11:14 +0800 Subject: [PATCH 017/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/core/lexer/test/LexerTest.java | 311 ++++++------------ 1 file changed, 106 insertions(+), 205 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java index b0d02908..b96a27dc 100644 --- a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java +++ b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java @@ -23,324 +23,225 @@ public class LexerTest { public Lexer lexer; @Test - @DisplayName("集合List") + @DisplayName("STRING") public void test0000() { - String text = "list = [\"name0\",\"name1\",\"name2\"]"; + String text = "name = \"Jessie\""; List words = lexer.getWords(text); log.info(words.toString()); assertTrue(words.size() == 3); int count = 0; - assertEquals(words.get(count++), "list"); + assertEquals(words.get(count++), "name"); assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "[\"name0\",\"name1\",\"name2\"]"); + assertEquals(words.get(count++), "\"Jessie\""); } @Test - @DisplayName("集合List内部拆分") + @DisplayName("CHAR") public void test0001() { - String text = "[\"name0\",\"name1\",\"name2\"]"; - List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); + String text = "ch = 'c'"; + List words = lexer.getWords(text); log.info(words.toString()); - assertTrue(words.size() == 7); + assertTrue(words.size() == 3); int count = 0; - assertEquals(words.get(count++), "["); - assertEquals(words.get(count++), "\"name0\""); - assertEquals(words.get(count++), ","); - assertEquals(words.get(count++), "\"name1\""); - assertEquals(words.get(count++), ","); - assertEquals(words.get(count++), "\"name2\""); - assertEquals(words.get(count++), "]"); + assertEquals(words.get(count++), "ch"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "'c'"); } @Test - @DisplayName("集合Map") + @DisplayName("MAP") public void test0002() { - String text = "map = {\"name\":\"tao.chen\",\"age\":29}"; + String text = "map = {\"name\" : \"Jessie\"}"; List words = lexer.getWords(text); log.info(words.toString()); assertTrue(words.size() == 3); int count = 0; assertEquals(words.get(count++), "map"); assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "{\"name\":\"tao.chen\",\"age\":29}"); + assertEquals(words.get(count++), "{\"name\" : \"Jessie\"}"); } @Test - @DisplayName("集合Map内部拆分") + @DisplayName("METHOD") public void test0003() { - String text = "{\"name\":\"tao.chen\",\"age\":29}"; - List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); + String text = "func call() {"; + List words = lexer.getWords(text); log.info(words.toString()); - assertTrue(words.size() == 9); + assertTrue(words.size() == 3); int count = 0; + assertEquals(words.get(count++), "func"); + assertEquals(words.get(count++), "call()"); assertEquals(words.get(count++), "{"); - assertEquals(words.get(count++), "\"name\""); - assertEquals(words.get(count++), ":"); - assertEquals(words.get(count++), "\"tao.chen\""); - assertEquals(words.get(count++), ","); - assertEquals(words.get(count++), "\"age\""); - assertEquals(words.get(count++), ":"); - assertEquals(words.get(count++), "29"); - assertEquals(words.get(count++), "}"); } @Test - @DisplayName("泛型") + @DisplayName("ARRAY_SIZE_INIT") public void test0004() { - String text = "map = HashMap()"; + String text = "horses = Horse[1]"; List words = lexer.getWords(text); log.info(words.toString()); assertTrue(words.size() == 3); int count = 0; - assertEquals(words.get(count++), "map"); + assertEquals(words.get(count++), "horses"); assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "HashMap()"); + assertEquals(words.get(count++), "Horse[1]"); } @Test - @DisplayName("泛型初始化内部拆分") + @DisplayName("ARRAY_LITERAL_INIT") public void test0005() { - String text = "HashMap()"; - List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); + String text = "horses = Horse[]{horse}"; + List words = lexer.getWords(text); log.info(words.toString()); assertTrue(words.size() == 3); int count = 0; - assertEquals(words.get(count++), "HashMap"); - assertEquals(words.get(count++), "("); - assertEquals(words.get(count++), ")"); + assertEquals(words.get(count++), "horses"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "Horse[]{horse}"); } @Test - @DisplayName("泛型类型内部拆分") + @DisplayName("ARRAY_VISIT_INDEX") public void test0006() { - String text = "HashMap"; - List words = lexer.getSubWords(text, '<', '>'); + String text = "horse = horses[0]"; + List words = lexer.getWords(text); log.info(words.toString()); - assertTrue(words.size() == 6); + assertTrue(words.size() == 4); int count = 0; - assertEquals(words.get(count++), "HashMap"); - assertEquals(words.get(count++), "<"); - assertEquals(words.get(count++), "String"); - assertEquals(words.get(count++), ","); - assertEquals(words.get(count++), "Object"); - assertEquals(words.get(count++), ">"); + assertEquals(words.get(count++), "horse"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "horses"); + assertEquals(words.get(count++), "[0]"); } @Test - @DisplayName("数组") + @DisplayName("GENERIC_TYPE") public void test0007() { - String text = "array = String[]{\"name0\",\"name1\",\"name2\"}"; + String text = "class Horse {"; List words = lexer.getWords(text); log.info(words.toString()); assertTrue(words.size() == 3); int count = 0; - assertEquals(words.get(count++), "array"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "String[]{\"name0\",\"name1\",\"name2\"}"); + assertEquals(words.get(count++), "class"); + assertEquals(words.get(count++), "Horse"); + assertEquals(words.get(count++), "{"); } @Test - @DisplayName("数组内部拆分") + @DisplayName("GENERIC_TYPE_INIT") public void test0008() { - String text = "String[]{\"name0\",\"name1\",\"name2\"}"; - List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); + String text = "horse = Horse()"; + List words = lexer.getWords(text); log.info(words.toString()); - assertTrue(words.size() == 10); + assertTrue(words.size() == 3); int count = 0; - assertEquals(words.get(count++), "String"); - assertEquals(words.get(count++), "["); - assertEquals(words.get(count++), "]"); - assertEquals(words.get(count++), "{"); - assertEquals(words.get(count++), "\"name0\""); - assertEquals(words.get(count++), ","); - assertEquals(words.get(count++), "\"name1\""); - assertEquals(words.get(count++), ","); - assertEquals(words.get(count++), "\"name2\""); - assertEquals(words.get(count++), "}"); + assertEquals(words.get(count++), "horse"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "Horse()"); } @Test - @DisplayName("关键字") + @DisplayName("MAP_SUBWORDS") public void test0009() { - String text = "class ServiceImpl extends AbsService impls Service{"; - List words = lexer.getWords(text); + String text = "{\"name\" : \"Jessie\"}"; + List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); - assertTrue(words.size() == 7); + assertTrue(words.size() == 5); int count = 0; - assertEquals(words.get(count++), "class"); - assertEquals(words.get(count++), "ServiceImpl"); - assertEquals(words.get(count++), "extends"); - assertEquals(words.get(count++), "AbsService"); - assertEquals(words.get(count++), "impls"); - assertEquals(words.get(count++), "Service"); assertEquals(words.get(count++), "{"); + assertEquals(words.get(count++), "\"name\""); + assertEquals(words.get(count++), ":"); + assertEquals(words.get(count++), "\"Jessie\""); + assertEquals(words.get(count++), "}"); } @Test - @DisplayName("方法") + @DisplayName("METHOD_SUBWORDS") public void test0010() { - String text = "func getAlias(@Deprecated String name,int age){"; - List words = lexer.getWords(text); - log.info(words.toString()); - assertTrue(words.size() == 3); - int count = 0; - assertEquals(words.get(count++), "func"); - assertEquals(words.get(count++), "getAlias(@Deprecated String name,int age)"); - assertEquals(words.get(count++), "{"); - } - - @Test - @DisplayName("方法内部拆分") - public void test0011() { - String text = "getAlias(@Deprecated String name,int age)"; + String text = "call(name, age)"; List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); - assertTrue(words.size() == 9); + assertTrue(words.size() == 6); int count = 0; - assertEquals(words.get(count++), "getAlias"); + assertEquals(words.get(count++), "call"); assertEquals(words.get(count++), "("); - assertEquals(words.get(count++), "@Deprecated"); - assertEquals(words.get(count++), "String"); assertEquals(words.get(count++), "name"); assertEquals(words.get(count++), ","); - assertEquals(words.get(count++), "int"); assertEquals(words.get(count++), "age"); assertEquals(words.get(count++), ")"); } @Test - @DisplayName("复杂嵌套") - public void test0012() { - String text = "list = [{},{}]"; - List words = lexer.getWords(text); - log.info(words.toString()); - assertTrue(words.size() == 3); - int count = 0; - assertEquals(words.get(count++), "list"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "[{},{}]"); - } - - @Test - @DisplayName("复杂嵌套内部拆分") - public void test0013() { - String text = "[{},{}]"; + @DisplayName("ARRAY_SIZE_INIT_SUBWORDS") + public void test0011() { + String text = "Horse[1]"; List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); - assertTrue(words.size() == 5); + assertTrue(words.size() == 4); int count = 0; + assertEquals(words.get(count++), "Horse"); assertEquals(words.get(count++), "["); - assertEquals(words.get(count++), "{}"); - assertEquals(words.get(count++), ","); - assertEquals(words.get(count++), "{}"); + assertEquals(words.get(count++), "1"); assertEquals(words.get(count++), "]"); } @Test - @DisplayName("访问字段") - public void test0014() { - String text = "fatherName = people.father.name"; - List words = lexer.getWords(text); - log.info(words.toString()); - assertTrue(words.size() == 5); - int count = 0; - assertEquals(words.get(count++), "fatherName"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "people"); - assertEquals(words.get(count++), ".father"); - assertEquals(words.get(count++), ".name"); - } - - @Test - @DisplayName("访问方法") - public void test0015() { - String text = "fatherName = people.father().name()"; - List words = lexer.getWords(text); - log.info(words.toString()); - assertTrue(words.size() == 5); - int count = 0; - assertEquals(words.get(count++), "fatherName"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "people"); - assertEquals(words.get(count++), ".father()"); - assertEquals(words.get(count++), ".name()"); - } - - @Test - @DisplayName("访问字段数组索引") - public void test0016() { - String text = "fatherName = people.father().name[0]"; - List words = lexer.getWords(text); + @DisplayName("ARRAY_LITERAL_INIT_SUBWORDS") + public void test0012() { + String text = "Horse[]{horse}"; + List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); assertTrue(words.size() == 6); int count = 0; - assertEquals(words.get(count++), "fatherName"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "people"); - assertEquals(words.get(count++), ".father()"); - assertEquals(words.get(count++), ".name"); - assertEquals(words.get(count++), "[0]"); + assertEquals(words.get(count++), "Horse"); + assertEquals(words.get(count++), "["); + assertEquals(words.get(count++), "]"); + assertEquals(words.get(count++), "{"); + assertEquals(words.get(count++), "horse"); + assertEquals(words.get(count++), "}"); } @Test - @DisplayName("访问方法数组索引") - public void test0017() { - String text = "fatherName = people.father().name()[0]"; - List words = lexer.getWords(text); + @DisplayName("ARRAY_VISIT_INDEX_SUBWORDS") + public void test0013() { + String text = "horses[0]"; + List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); - assertTrue(words.size() == 6); + assertTrue(words.size() == 4); int count = 0; - assertEquals(words.get(count++), "fatherName"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "people"); - assertEquals(words.get(count++), ".father()"); - assertEquals(words.get(count++), ".name()"); - assertEquals(words.get(count++), "[0]"); + assertEquals(words.get(count++), "horses"); + assertEquals(words.get(count++), "["); + assertEquals(words.get(count++), "0"); + assertEquals(words.get(count++), "]"); } @Test - @DisplayName("逻辑操作符") - public void test0018() { - String text = "flag = !(x+1>0 && y<100) && s==\"test\" || s instanceof Object"; - List words = lexer.getWords(text); + @DisplayName("GENERIC_TYPE_SUBWORDS") + public void test0014() { + String text = "Horse"; + List words = lexer.getSubWords(text, '<', '>'); log.info(words.toString()); - assertTrue(words.size() == 12); + assertTrue(words.size() == 6); int count = 0; - assertEquals(words.get(count++), "flag"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "!"); - assertEquals(words.get(count++), "(x+1>0 && y<100)"); - assertEquals(words.get(count++), "&&"); - assertEquals(words.get(count++), "s"); - assertEquals(words.get(count++), "=="); - assertEquals(words.get(count++), "\"test\""); - assertEquals(words.get(count++), "||"); - assertEquals(words.get(count++), "s"); - assertEquals(words.get(count++), "instanceof"); - assertEquals(words.get(count++), "Object"); + assertEquals(words.get(count++), "Horse"); + assertEquals(words.get(count++), "<"); + assertEquals(words.get(count++), "T"); + assertEquals(words.get(count++), ","); + assertEquals(words.get(count++), "K"); + assertEquals(words.get(count++), ">"); } @Test - @DisplayName("计算操作符") - public void test0019() { - String text = "number = x%2*100/2 + y - z"; - List words = lexer.getWords(text); + @DisplayName("GENERIC_TYPE_INIT_SUBWORDS") + public void test0015() { + String text = "Horse()"; + List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); - assertTrue(words.size() == 13); + assertTrue(words.size() == 3); int count = 0; - assertEquals(words.get(count++), "number"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "x"); - assertEquals(words.get(count++), "%"); - assertEquals(words.get(count++), "2"); - assertEquals(words.get(count++), "*"); - assertEquals(words.get(count++), "100"); - assertEquals(words.get(count++), "/"); - assertEquals(words.get(count++), "2"); - assertEquals(words.get(count++), "+"); - assertEquals(words.get(count++), "y"); - assertEquals(words.get(count++), "-"); - assertEquals(words.get(count++), "z"); + assertEquals(words.get(count++), "Horse"); + assertEquals(words.get(count++), "("); + assertEquals(words.get(count++), ")"); } } -- Gitee From f2ba4e8d4c8c97492ef7656ac7b351c1377f4f52 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 19 Mar 2021 14:24:41 +0800 Subject: [PATCH 018/121] =?UTF-8?q?=E6=95=B4=E7=90=86=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/core/lexer/test/LexerTest.java | 211 +++++++++++++----- 1 file changed, 151 insertions(+), 60 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java index b96a27dc..1cfca8f8 100644 --- a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java +++ b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java @@ -62,113 +62,122 @@ public class LexerTest { } @Test - @DisplayName("METHOD") + @DisplayName("MAP_SUBWORDS") public void test0003() { - String text = "func call() {"; - List words = lexer.getWords(text); + String text = "{\"name\" : \"Jessie\"}"; + List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); - assertTrue(words.size() == 3); + assertTrue(words.size() == 5); int count = 0; - assertEquals(words.get(count++), "func"); - assertEquals(words.get(count++), "call()"); assertEquals(words.get(count++), "{"); + assertEquals(words.get(count++), "\"name\""); + assertEquals(words.get(count++), ":"); + assertEquals(words.get(count++), "\"Jessie\""); + assertEquals(words.get(count++), "}"); } @Test - @DisplayName("ARRAY_SIZE_INIT") + @DisplayName("MAP_COMPLEX_NESTING") public void test0004() { - String text = "horses = Horse[1]"; - List words = lexer.getWords(text); + String text = "{\"horse\" : {\"name\" : \"Jessie\"}}"; + List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); - assertTrue(words.size() == 3); + assertTrue(words.size() == 5); int count = 0; - assertEquals(words.get(count++), "horses"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "Horse[1]"); + assertEquals(words.get(count++), "{"); + assertEquals(words.get(count++), "\"horse\""); + assertEquals(words.get(count++), ":"); + assertEquals(words.get(count++), "{\"name\" : \"Jessie\"}"); + assertEquals(words.get(count++), "}"); } @Test - @DisplayName("ARRAY_LITERAL_INIT") + @DisplayName("METHOD") public void test0005() { - String text = "horses = Horse[]{horse}"; + String text = "func call() {"; List words = lexer.getWords(text); log.info(words.toString()); assertTrue(words.size() == 3); int count = 0; - assertEquals(words.get(count++), "horses"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "Horse[]{horse}"); + assertEquals(words.get(count++), "func"); + assertEquals(words.get(count++), "call()"); + assertEquals(words.get(count++), "{"); } @Test - @DisplayName("ARRAY_VISIT_INDEX") + @DisplayName("METHOD_SUBWORDS") public void test0006() { - String text = "horse = horses[0]"; - List words = lexer.getWords(text); + String text = "call(name, age)"; + List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); - assertTrue(words.size() == 4); + assertTrue(words.size() == 6); int count = 0; - assertEquals(words.get(count++), "horse"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "horses"); - assertEquals(words.get(count++), "[0]"); + assertEquals(words.get(count++), "call"); + assertEquals(words.get(count++), "("); + assertEquals(words.get(count++), "name"); + assertEquals(words.get(count++), ","); + assertEquals(words.get(count++), "age"); + assertEquals(words.get(count++), ")"); } @Test - @DisplayName("GENERIC_TYPE") + @DisplayName("LIST") public void test0007() { - String text = "class Horse {"; + String text = "horses = [horse0, horse1, horse2]"; List words = lexer.getWords(text); log.info(words.toString()); assertTrue(words.size() == 3); int count = 0; - assertEquals(words.get(count++), "class"); - assertEquals(words.get(count++), "Horse"); - assertEquals(words.get(count++), "{"); + assertEquals(words.get(count++), "horses"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "[horse0, horse1, horse2]"); } @Test - @DisplayName("GENERIC_TYPE_INIT") + @DisplayName("LIST_SUBWORDS") public void test0008() { - String text = "horse = Horse()"; - List words = lexer.getWords(text); + String text = "[horse0, horse1, horse2]"; + List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); - assertTrue(words.size() == 3); + assertTrue(words.size() == 7); int count = 0; - assertEquals(words.get(count++), "horse"); - assertEquals(words.get(count++), "="); - assertEquals(words.get(count++), "Horse()"); + assertEquals(words.get(count++), "["); + assertEquals(words.get(count++), "horse0"); + assertEquals(words.get(count++), ","); + assertEquals(words.get(count++), "horse1"); + assertEquals(words.get(count++), ","); + assertEquals(words.get(count++), "horse2"); + assertEquals(words.get(count++), "]"); } @Test - @DisplayName("MAP_SUBWORDS") + @DisplayName("LIST_COMPLEX_NESTING") public void test0009() { - String text = "{\"name\" : \"Jessie\"}"; + String text = "[[horse0], horse1, horse2]"; List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); - assertTrue(words.size() == 5); + assertTrue(words.size() == 7); int count = 0; - assertEquals(words.get(count++), "{"); - assertEquals(words.get(count++), "\"name\""); - assertEquals(words.get(count++), ":"); - assertEquals(words.get(count++), "\"Jessie\""); - assertEquals(words.get(count++), "}"); + assertEquals(words.get(count++), "["); + assertEquals(words.get(count++), "[horse0]"); + assertEquals(words.get(count++), ","); + assertEquals(words.get(count++), "horse1"); + assertEquals(words.get(count++), ","); + assertEquals(words.get(count++), "horse2"); + assertEquals(words.get(count++), "]"); } @Test - @DisplayName("METHOD_SUBWORDS") + @DisplayName("ARRAY_SIZE_INIT") public void test0010() { - String text = "call(name, age)"; - List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); + String text = "horses = Horse[1]"; + List words = lexer.getWords(text); log.info(words.toString()); - assertTrue(words.size() == 6); + assertTrue(words.size() == 3); int count = 0; - assertEquals(words.get(count++), "call"); - assertEquals(words.get(count++), "("); - assertEquals(words.get(count++), "name"); - assertEquals(words.get(count++), ","); - assertEquals(words.get(count++), "age"); - assertEquals(words.get(count++), ")"); + assertEquals(words.get(count++), "horses"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "Horse[1]"); } @Test @@ -186,8 +195,21 @@ public class LexerTest { } @Test - @DisplayName("ARRAY_LITERAL_INIT_SUBWORDS") + @DisplayName("ARRAY_LITERAL_INIT") public void test0012() { + String text = "horses = Horse[]{horse}"; + List words = lexer.getWords(text); + log.info(words.toString()); + assertTrue(words.size() == 3); + int count = 0; + assertEquals(words.get(count++), "horses"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "Horse[]{horse}"); + } + + @Test + @DisplayName("ARRAY_LITERAL_INIT_SUBWORDS") + public void test0013() { String text = "Horse[]{horse}"; List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); @@ -201,9 +223,23 @@ public class LexerTest { assertEquals(words.get(count++), "}"); } + @Test + @DisplayName("ARRAY_VISIT_INDEX") + public void test0014() { + String text = "horse = horses[0]"; + List words = lexer.getWords(text); + log.info(words.toString()); + assertTrue(words.size() == 4); + int count = 0; + assertEquals(words.get(count++), "horse"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "horses"); + assertEquals(words.get(count++), "[0]"); + } + @Test @DisplayName("ARRAY_VISIT_INDEX_SUBWORDS") - public void test0013() { + public void test0015() { String text = "horses[0]"; List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); @@ -215,9 +251,22 @@ public class LexerTest { assertEquals(words.get(count++), "]"); } + @Test + @DisplayName("GENERIC_TYPE") + public void test0016() { + String text = "class Horse {"; + List words = lexer.getWords(text); + log.info(words.toString()); + assertTrue(words.size() == 3); + int count = 0; + assertEquals(words.get(count++), "class"); + assertEquals(words.get(count++), "Horse"); + assertEquals(words.get(count++), "{"); + } + @Test @DisplayName("GENERIC_TYPE_SUBWORDS") - public void test0014() { + public void test0017() { String text = "Horse"; List words = lexer.getSubWords(text, '<', '>'); log.info(words.toString()); @@ -231,9 +280,38 @@ public class LexerTest { assertEquals(words.get(count++), ">"); } + @Test + @DisplayName("GENERIC_TYPE_COMPLEX_NESTING") + public void test0018() { + String text = "Horse, Object>"; + List words = lexer.getSubWords(text, '<', '>'); + log.info(words.toString()); + assertTrue(words.size() == 6); + int count = 0; + assertEquals(words.get(count++), "Horse"); + assertEquals(words.get(count++), "<"); + assertEquals(words.get(count++), "Horse"); + assertEquals(words.get(count++), ","); + assertEquals(words.get(count++), "Object"); + assertEquals(words.get(count++), ">"); + } + + @Test + @DisplayName("GENERIC_TYPE_INIT") + public void test0019() { + String text = "horse = Horse()"; + List words = lexer.getWords(text); + log.info(words.toString()); + assertTrue(words.size() == 3); + int count = 0; + assertEquals(words.get(count++), "horse"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "Horse()"); + } + @Test @DisplayName("GENERIC_TYPE_INIT_SUBWORDS") - public void test0015() { + public void test0020() { String text = "Horse()"; List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); log.info(words.toString()); @@ -244,4 +322,17 @@ public class LexerTest { assertEquals(words.get(count++), ")"); } + @Test + @DisplayName("GENERIC_TYPE_INIT_COMPLEX_NESTING") + public void test0021() { + String text = "Horse, Object>()"; + List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); + log.info(words.toString()); + assertTrue(words.size() == 3); + int count = 0; + assertEquals(words.get(count++), "Horse, Object>"); + assertEquals(words.get(count++), "("); + assertEquals(words.get(count++), ")"); + } + } -- Gitee From bc89ad69533f37e821a30f2aa91f1ca4a22c01eb Mon Sep 17 00:00:00 2001 From: chenT Date: Sun, 21 Mar 2021 13:40:12 +0800 Subject: [PATCH 019/121] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=A1=88=E4=BE=8B=EF=BC=8C=E5=B9=B6=E6=B7=BB=E5=8A=A0=E5=88=A4?= =?UTF-8?q?=E7=A9=BA=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/compile/action/ElementExpressDeclarer.java | 12 +++++++----- .../sum/spirit/core/element/ElementBuilderImpl.java | 6 ++++-- .../java/com/sum/spirit/core/lexer/CoreLexer.java | 9 +++------ .../com/sum/spirit/core/lexer/test/LexerTest.java | 4 ++-- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java index e963860f..bd1c8a24 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java @@ -80,11 +80,13 @@ public class ElementExpressDeclarer extends AbstractElementAction { if (secondToken.isSubexpress()) { Statement statement = secondToken.getValue(); Statement subStatement = statement.subStmt(1, statement.indexOf(";")); - Element subElement = builder.rebuild(subStatement); - IVariable variable = elementVisiter.visitElement(clazz, subElement, context); - if (variable != null) { - variable.blockId = context.getBlockId(); - context.variables.add(variable); + if (subStatement.size() > 0) { + Element subElement = builder.rebuild(subStatement); + IVariable variable = elementVisiter.visitElement(clazz, subElement, context); + if (variable != null) { + variable.blockId = context.getBlockId(); + context.variables.add(variable); + } } } } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java index 6657a2c8..ffe75c37 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java @@ -18,6 +18,8 @@ import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.SyntaxTree; import com.sum.spirit.core.element.entity.Token; +import cn.hutool.core.lang.Assert; + @Component public class ElementBuilderImpl implements ElementBuilder { @@ -69,9 +71,9 @@ public class ElementBuilderImpl implements ElementBuilder { @Override public Element rebuild(Statement statement) { + Assert.notEmpty(statement, "statement cannot be empty!"); Element element = build(statement.toString()); - // 注意:新建一个element是为了得到分析的语法,赋值是为了复用token - element.list = statement; + element.list = statement;// 注意:新建一个element是为了得到分析的语法,赋值是为了复用token return element; } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java index c55ef005..c9996a54 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java @@ -5,7 +5,6 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.DependsOn; @@ -40,10 +39,7 @@ public class CoreLexer extends AbstractCharsHandler implements Lexer, Initializi @Override public List getWords(String text) { - // 拆分方法体时,会传入空的text - if (StringUtils.isEmpty(text)) { - return new ArrayList<>(); - } + Assert.notBlank(text, "text cannot be blank!"); // 处理字符串 StringBuilder builder = new StringBuilder(text.trim()); LexerContext context = new LexerContext(builder); @@ -62,12 +58,13 @@ public class CoreLexer extends AbstractCharsHandler implements Lexer, Initializi @Override public List getSubWords(String text, Character... splitChars) { + Assert.notBlank(text, "text cannot be blank!"); // 处理字符串 StringBuilder builder = new StringBuilder(text.trim()); LexerContext context = new LexerContext(builder, splitChars); handle(context, builder, new CursorAction(borderAction)); // 校验 - Assert.notNull(context.words, "words of context can not be null!"); + Assert.notNull(context.words, "words of context cannot be null!"); // 继续拆分 List words = new ArrayList<>(); for (String word : context.words) { diff --git a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java index 1cfca8f8..bf9ca255 100644 --- a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java +++ b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java @@ -51,12 +51,12 @@ public class LexerTest { @Test @DisplayName("MAP") public void test0002() { - String text = "map = {\"name\" : \"Jessie\"}"; + String text = "horse = {\"name\" : \"Jessie\"}"; List words = lexer.getWords(text); log.info(words.toString()); assertTrue(words.size() == 3); int count = 0; - assertEquals(words.get(count++), "map"); + assertEquals(words.get(count++), "horse"); assertEquals(words.get(count++), "="); assertEquals(words.get(count++), "{\"name\" : \"Jessie\"}"); } -- Gitee From 6d546899b6746fd4a0414eb35f63047cad1cb8a2 Mon Sep 17 00:00:00 2001 From: chenT Date: Sun, 21 Mar 2021 16:10:31 +0800 Subject: [PATCH 020/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/common/utils/Lists.java | 19 ++++++++++--- .../sum/spirit/core/compile/ClassVisiter.java | 2 +- .../sum/spirit/core/api/SemanticParser.java | 12 +++------ .../action/AbstractSemanticParser.java | 27 ++++++++++++++----- .../element/action/SemanticParserImpl.java | 5 ++-- .../spirit/core/element/entity/Modifiers.java | 2 +- .../core/lexer/action/RegionAction.java | 12 ++++----- 7 files changed, 50 insertions(+), 29 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java index e4648885..c0f8be94 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java @@ -9,7 +9,7 @@ import cn.hutool.core.collection.CollUtil; public class Lists { @SafeVarargs - public static List toList(T... items) { + public static List toListNonNull(T... items) { if (items == null || items.length == 0) { return new ArrayList(); } @@ -84,7 +84,7 @@ public class Lists { return CollUtil.findOne(collection, item -> matcher.accept(item)); } - public static List filterByCondition(List list, Filter filter) { + public static List filterStoppable(List list, Filter filter) { List items = new ArrayList<>(); Iterator iterable = list.iterator(); while (iterable.hasNext()) { @@ -100,8 +100,8 @@ public class Lists { } @SuppressWarnings("unchecked") - public static List filterByCondition(List list, Filter filter, Factory factory) { - List items = filterByCondition(list, filter); + public static List filterStoppable(List list, Filter filter, Factory factory) { + List items = filterStoppable(list, filter); List list0 = new ArrayList<>(); items.forEach(item -> list0.add((V) factory.accept(item))); return list0; @@ -134,6 +134,17 @@ public class Lists { return null; } + @SuppressWarnings("unchecked") + public static List collectAll(List list, Matcher matcher, Factory factory) { + List list0 = new ArrayList<>(); + for (T item : list) { + if (matcher.accept(item)) { + list0.add((V) factory.accept(item)); + } + } + return list0; + } + public static interface Matcher { boolean accept(T t); } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java index acc124a5..49b5015c 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java @@ -73,7 +73,7 @@ public class ClassVisiter { Statement statement = methodToken.getValue(); List statements = statement.subStmt("(", ")").splitStmt(","); for (Statement paramStmt : statements) { - List annotations = Lists.filterByCondition(paramStmt, token -> token.isAnnotation(), token -> new IAnnotation(token)); + List annotations = Lists.filterStoppable(paramStmt, token -> token.isAnnotation(), token -> new IAnnotation(token)); IParameter parameter = new IParameter(annotations, builder.rebuild(paramStmt)); parameter.setType(factory.create(clazz, paramStmt.get(0))); method.parameters.add(parameter); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java index 235b9c4a..fac85194 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java @@ -6,17 +6,13 @@ import com.sum.spirit.core.element.entity.Token; public interface SemanticParser { - List getTokens(List words, boolean insideType); + List getTokens(List words); - default List getTokens(List words) { - return getTokens(words, false); - } + List getTokensInsideType(List words); - Token getToken(String word, boolean insideType); + Token getToken(String word); - default Token getToken(String word) { - return getToken(word, false); - } + Token getTokenInsideType(String word); boolean isPath(String word); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index ebe6a2a1..3c10c7f6 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -1,6 +1,5 @@ package com.sum.spirit.core.element.action; -import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; @@ -9,6 +8,7 @@ import com.sum.spirit.common.enums.LiteralEnum; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.common.enums.TypeEnum; +import com.sum.spirit.common.utils.Lists; import com.sum.spirit.core.api.SemanticParser; import com.sum.spirit.core.element.entity.Token; @@ -28,12 +28,23 @@ public abstract class AbstractSemanticParser implements SemanticParser { public static final Pattern PREFIX_PATTERN = Pattern.compile("^(\\.)?\\w+$"); @Override - public List getTokens(List words, boolean insideType) { - List tokens = new ArrayList<>(); - for (String word : words) { - tokens.add(getToken(word, insideType)); - } - return tokens; + public List getTokens(List words) { + return Lists.collectAll(words, word -> true, word -> getToken(word)); + } + + @Override + public List getTokensInsideType(List words) { + return Lists.collectAll(words, word -> true, word -> getTokenInsideType(word)); + } + + @Override + public Token getToken(String word) { + return getToken(word, false); + } + + @Override + public Token getTokenInsideType(String word) { + return getToken(word, true); } @Override @@ -168,4 +179,6 @@ public abstract class AbstractSemanticParser implements SemanticParser { return word.substring(1, word.length() - 1); } + public abstract Token getToken(String word, boolean insideType); + } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java index 27fbebf9..41098ead 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java @@ -89,10 +89,11 @@ public class SemanticParserImpl extends AbstractSemanticParser { List tokens = null; // 如果第一个单词是一个前缀的话,则添加前缀 if (PREFIX_PATTERN.matcher(first).matches()) { - tokens = getTokens(words.subList(1, words.size()), insideType); + List subWords = words.subList(1, words.size()); + tokens = insideType ? getTokensInsideType(subWords) : getTokens(subWords); tokens.add(0, new Token(TokenTypeEnum.PREFIX, first)); } else { - tokens = getTokens(words, insideType); + tokens = insideType ? getTokensInsideType(words) : getTokens(words); } Assert.notNull(tokens, "Tokens can not be null!"); return new Statement(tokens); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Modifiers.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Modifiers.java index 6e5fc548..1018f6b6 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Modifiers.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Modifiers.java @@ -9,7 +9,7 @@ import com.sum.spirit.core.element.frame.KeywordTokenBox; public class Modifiers extends KeywordTokenBox { public Modifiers(List tokens) { - super(Lists.filterByCondition(tokens, token -> token.isModifier())); + super(Lists.filterStoppable(tokens, token -> token.isModifier())); } @Override diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java index e6ca4ed5..c42272b8 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java @@ -52,20 +52,20 @@ public class RegionAction extends AbstractLexerAction { if (ch == '"') { Region region = findRegion(builder, context.index, '"', '"'); - pushStack(event, Lists.toList(region), "@str"); + pushStack(event, Lists.toListNonNull(region), "@str"); } else if (ch == '\'') { Region region = findRegion(builder, context.index, '\'', '\''); - pushStack(event, Lists.toList(region), "@char"); + pushStack(event, Lists.toListNonNull(region), "@char"); } else if (ch == '{') { Region region = findRegion(builder, context.index, '{', '}'); - pushStack(event, Lists.toList(region), "@map"); + pushStack(event, Lists.toListNonNull(region), "@map"); } else if (ch == '(') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; Region region1 = findRegion(builder, context.index, '(', ')'); - pushStack(event, Lists.toList(region0, region1), "@invoke_like"); + pushStack(event, Lists.toListNonNull(region0, region1), "@invoke_like"); resetIndex(event); } else if (ch == '[') { @@ -85,14 +85,14 @@ public class RegionAction extends AbstractLexerAction { region2 = findRegion(builder, region1.endIndex + 1, '{', '}'); } } - pushStack(event, Lists.toList(region0, region1, region2), "@array_like"); + pushStack(event, Lists.toListNonNull(region0, region1, region2), "@array_like"); resetIndex(event); } else if (ch == '<') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; Region region1 = findRegion(builder, context.index, '<', '>'); Region region2 = isCharAt(builder, region1.endIndex, '(') ? findRegion(builder, region1.endIndex, '(', ')') : null; - pushStack(event, Lists.toList(region0, region1, region2), "@generic"); + pushStack(event, Lists.toListNonNull(region0, region1, region2), "@generic"); resetIndex(event); } } -- Gitee From e81d9c36a1b0535d72e31a9ee25ef9a4959f3386 Mon Sep 17 00:00:00 2001 From: chenT Date: Sun, 21 Mar 2021 16:21:30 +0800 Subject: [PATCH 021/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/common/utils/Splitter.java | 2 +- .../spirit/core/element/action/SemanticParserImpl.java | 10 ++++++---- .../spirit/core/lexer/action/AbstractLexerAction.java | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java index 2d3ea56f..9dbc6e9b 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java @@ -11,7 +11,7 @@ import cn.hutool.core.lang.Assert; public class Splitter { public static List splitByIndexsTrimRemain(String str, List indexs) { - Assert.isTrue(indexs != null && indexs.size() > 0, "indexs can not be empty!"); + Assert.isTrue(indexs != null && indexs.size() > 0, "indexs cannot be empty!"); List strs = new ArrayList<>(); int lastIndex = 0; for (Integer index : indexs) { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java index 41098ead..d971b51e 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java @@ -71,8 +71,7 @@ public class SemanticParserImpl extends AbstractSemanticParser { token.value = getStatement(word, true); } else if (token.isArrayInit() || token.isList() || token.isMap() || token.isSubexpress() || token.isInvoke()) { - // 拆分数组是为了更好的添加new这个关键字 - token.value = getStatement(word, false); + token.value = getStatement(word, false);// 拆分数组是为了更好的添加new这个关键字 } else { token.value = word; @@ -83,19 +82,22 @@ public class SemanticParserImpl extends AbstractSemanticParser { if (insideType && (!word.contains("<") && !word.contains(">"))) { return word; } + // 如果是类型,则直接用尖括号进行拆分,如果是其他,则不使用尖括号进行拆分 List words = insideType ? lexer.getSubWords(word, '<', '>') : lexer.getSubWords(word, '(', ')', '[', ']', '{', '}'); - String first = words.get(0); List tokens = null; + String first = words.get(0); // 如果第一个单词是一个前缀的话,则添加前缀 if (PREFIX_PATTERN.matcher(first).matches()) { List subWords = words.subList(1, words.size()); tokens = insideType ? getTokensInsideType(subWords) : getTokens(subWords); tokens.add(0, new Token(TokenTypeEnum.PREFIX, first)); + } else { tokens = insideType ? getTokensInsideType(words) : getTokens(words); } - Assert.notNull(tokens, "Tokens can not be null!"); + + Assert.notNull(tokens, "Tokens cannot be null!"); return new Statement(tokens); } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java index 5827886c..0991c963 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java @@ -25,7 +25,7 @@ public abstract class AbstractLexerAction implements CharAction { public Region mergeRegions(List regions) { Region finalRegion = new Region(-1, -1); for (Region region : regions) { - Assert.notNull(region, "Region can not be null!"); + Assert.notNull(region, "Region cannot be null!"); if (finalRegion.startIndex == -1 || region.startIndex < finalRegion.startIndex) { finalRegion.startIndex = region.startIndex; } @@ -33,7 +33,7 @@ public abstract class AbstractLexerAction implements CharAction { finalRegion.endIndex = region.endIndex; } } - Assert.isTrue(finalRegion.startIndex != -1 && finalRegion.endIndex != -1, "The index of region can not be -1!"); + Assert.isTrue(finalRegion.startIndex != -1 && finalRegion.endIndex != -1, "The index of region cannot be -1!"); return finalRegion; } -- Gitee From aaba51cbb59ecb13f26b62f81d8c0432405b867a Mon Sep 17 00:00:00 2001 From: chenT Date: Sun, 21 Mar 2021 16:27:51 +0800 Subject: [PATCH 022/121] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/element/DocumentReaderImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DocumentReaderImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DocumentReaderImpl.java index 589873c3..9ef2985b 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DocumentReaderImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DocumentReaderImpl.java @@ -11,6 +11,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.constants.Constants; import com.sum.spirit.common.utils.ConfigUtils; import com.sum.spirit.core.api.DocumentReader; +import com.sum.spirit.core.api.ElementBuilder; import com.sum.spirit.core.element.entity.Document; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Line; @@ -22,7 +23,7 @@ import cn.hutool.core.io.IoUtil; public class DocumentReaderImpl implements DocumentReader { @Autowired - public ElementBuilderImpl builder; + public ElementBuilder builder; @Override public Document read(String fileName, InputStream input) { -- Gitee From 59f9a22814bf6f7aa3372a576bb9feec531e63c7 Mon Sep 17 00:00:00 2001 From: chenT Date: Sun, 21 Mar 2021 17:40:19 +0800 Subject: [PATCH 023/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/element/utils/StmtFormat.java | 140 ++++++++++-------- 1 file changed, 76 insertions(+), 64 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java index 70692919..d5117c76 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java @@ -14,81 +14,93 @@ public class StmtFormat { List tokens = statement.copyTokens(); - for (int i = tokens.size() - 1; i >= 1; i--) { - tokens.add(i, new Token(TokenTypeEnum.SEPARATOR, " ")); + for (int index = tokens.size() - 1; index >= 1; index--) { + tokens.add(index, new Token(TokenTypeEnum.SEPARATOR, " ")); } - for (int i = 0; i < tokens.size(); i++) { - Token token = tokens.get(i); + for (int index = 0; index < tokens.size(); index++) { + Token token = tokens.get(index); if (token.isSeparator() && " ".equals(token.toString())) { - Token lastToken = tokens.get(i - 1); - Token nextToken = tokens.get(i + 1); - if (lastToken.isOperator()) { - if ("!".equals(lastToken.toString())) { - tokens.remove(i); - continue; - - } else if ("++".equals(lastToken.toString()) || "--".equals(lastToken.toString())) { - OperandEnum operandEnum = lastToken.attr(AttributeEnum.OPERAND); - if (operandEnum == OperandEnum.RIGHT) { - tokens.remove(i); - continue; - } - - } else if ("-".equals(lastToken.toString())) { - OperandEnum operandEnum = lastToken.attr(AttributeEnum.OPERAND); - if (operandEnum == OperandEnum.RIGHT) { - tokens.remove(i); - continue; - } - } - - } else if (lastToken.isSeparator()) { - if ("[".equals(lastToken.toString()) || "(".equals(lastToken.toString()) || "<".equals(lastToken.toString())) { - tokens.remove(i); - continue; - } - - } else if (lastToken.isCustomPrefix()) { - tokens.remove(i); + Token lastToken = tokens.get(index - 1); + Token nextToken = tokens.get(index + 1); + // 处理上一节点 + boolean isFinish = dealLastToken(tokens, index, lastToken, nextToken); + if (isFinish) { continue; } + // 处理下一节点 + dealNextToken(tokens, index, lastToken, nextToken); + } + } - if (nextToken.isOperator()) { - if ("++".equals(nextToken.toString()) || "--".equals(nextToken.toString())) { - OperandEnum operandEnum = nextToken.attr(AttributeEnum.OPERAND); - if (operandEnum == OperandEnum.LEFT) { - tokens.remove(i); - continue; - } - } - - } else if (nextToken.isSeparator()) { - if ("[".equals(nextToken.toString()) || "(".equals(nextToken.toString()) || "<".equals(nextToken.toString()) - || "]".equals(nextToken.toString()) || ")".equals(nextToken.toString()) || ">".equals(nextToken.toString()) - || ",".equals(nextToken.toString()) || ";".equals(nextToken.toString())) { - - if (lastToken.isKeyword() && "(".equals(nextToken.toString())) { - continue;// if (express) { - - } else { - tokens.remove(i); - continue; - } - } - - } else if (nextToken.isVisit()) { - tokens.remove(i); - continue; + return tokens; + } - } else if (nextToken.isCustomSuffix()) { - tokens.remove(i); - continue; + public static boolean dealLastToken(List tokens, int index, Token lastToken, Token nextToken) { + if (lastToken.isOperator()) { + if ("!".equals(lastToken.toString())) { + tokens.remove(index); + return true; + + } else if ("-".equals(lastToken.toString())) { + OperandEnum operandEnum = lastToken.attr(AttributeEnum.OPERAND); + if (operandEnum == OperandEnum.RIGHT) { + tokens.remove(index); + return true; } } + + } else if (lastToken.isSeparator()) { + if ("[".equals(lastToken.toString()) || "(".equals(lastToken.toString()) || "<".equals(lastToken.toString())) { + tokens.remove(index); + return true; + } + + } else if (lastToken.isCustomPrefix()) { + tokens.remove(index); + return true; } - return tokens; + return false; + } + + public static void dealNextToken(List tokens, int index, Token lastToken, Token nextToken) { + if (nextToken.isOperator()) { + if ("++".equals(nextToken.toString()) || "--".equals(nextToken.toString())) { + OperandEnum operandEnum = nextToken.attr(AttributeEnum.OPERAND); + if (operandEnum == OperandEnum.LEFT) { + tokens.remove(index); + return; + } + } + + } else if (nextToken.isSeparator()) { + if ("[".equals(nextToken.toString()) || "(".equals(nextToken.toString()) || "<".equals(nextToken.toString())) { + if (lastToken.isKeyword() && "(".equals(nextToken.toString())) {// if (express) { + return; + + } else { + tokens.remove(index); + return; + } + + } else if ("]".equals(nextToken.toString()) || ")".equals(nextToken.toString()) || ">".equals(nextToken.toString())) { + tokens.remove(index); + return; + + } else if (",".equals(nextToken.toString()) || ";".equals(nextToken.toString())) { + tokens.remove(index); + return; + } + + } else if (nextToken.isVisit()) { + tokens.remove(index); + return; + + } else if (nextToken.isCustomSuffix()) { + tokens.remove(index); + return; + } } } -- Gitee From 0e8c71fc53af5076eb3d6ddc40b2c6fcb82bbbd9 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Mon, 22 Mar 2021 09:33:28 +0800 Subject: [PATCH 024/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/element/action/SemanticParserImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java index d971b51e..fa87370f 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java @@ -87,6 +87,7 @@ public class SemanticParserImpl extends AbstractSemanticParser { List words = insideType ? lexer.getSubWords(word, '<', '>') : lexer.getSubWords(word, '(', ')', '[', ']', '{', '}'); List tokens = null; String first = words.get(0); + // 如果第一个单词是一个前缀的话,则添加前缀 if (PREFIX_PATTERN.matcher(first).matches()) { List subWords = words.subList(1, words.size()); -- Gitee From 2fcbb0aa3ffd089e1bc250b60676e350b1fd078b Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 23 Mar 2021 10:16:57 +0800 Subject: [PATCH 025/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/element/utils/StmtFormat.java | 9 ++----- .../output/java/action/SeparatorAction.java | 24 ++++++++++--------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java index d5117c76..49925f46 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java @@ -76,13 +76,8 @@ public class StmtFormat { } else if (nextToken.isSeparator()) { if ("[".equals(nextToken.toString()) || "(".equals(nextToken.toString()) || "<".equals(nextToken.toString())) { - if (lastToken.isKeyword() && "(".equals(nextToken.toString())) {// if (express) { - return; - - } else { - tokens.remove(index); - return; - } + tokens.remove(index); + return; } else if ("]".equals(nextToken.toString()) || ")".equals(nextToken.toString()) || ">".equals(nextToken.toString())) { tokens.remove(index); diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java index b2c24581..e06eec70 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java @@ -24,22 +24,24 @@ public class SeparatorAction extends AbstractElementAction { insertBrackets(clazz, element); } - if (element.isDeclare() || element.isDeclareAssign() || element.isAssign() || element.isFieldAssign() || // - element.isInvoke() || element.isReturn() || element.isSuper() || element.isThis() || // - element.isThrow() || element.isContinue() || element.isBreak()) { + if (element.isDeclare() || element.isDeclareAssign() || element.isAssign() || // + element.isFieldAssign() || element.isInvoke() || element.isReturn() || // + element.isSuper() || element.isThis() || element.isThrow() || // + element.isContinue() || element.isBreak()) { addLineEnd(clazz, element); } } public void insertBrackets(IClass clazz, Statement statement) { - // if text { - // }catch Exception e{ - int index = findLastKeyword(statement); - statement.add(index + 1, new Token(TokenTypeEnum.SEPARATOR, "(")); - if ("{".equals(statement.last())) { - statement.add(statement.size() - 1, new Token(TokenTypeEnum.SEPARATOR, ")")); - } else { - statement.add(new Token(TokenTypeEnum.SEPARATOR, ")")); + int keywordIndex = findLastKeyword(statement); + int startIndex = keywordIndex >= 0 ? keywordIndex + 1 : -1; + int endIndex = "{".equals(statement.last()) ? statement.size() - 1 : statement.size(); + if (endIndex != -1) { + Statement subStatement = statement.subStmt(startIndex, endIndex); + subStatement.add(0, new Token(TokenTypeEnum.SEPARATOR, "(")); + subStatement.add(new Token(TokenTypeEnum.SEPARATOR, ")")); + Token subexpress = new Token(TokenTypeEnum.SUBEXPRESS, subStatement); + statement.replaceTokens(startIndex, endIndex, subexpress); } } -- Gitee From 83f4d85b1c970d56d53dc9c72f160017a6ae764f Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 23 Mar 2021 10:59:15 +0800 Subject: [PATCH 026/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/lexer/CoreLexer.java | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java index c9996a54..eb92e2c4 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java @@ -37,35 +37,36 @@ public class CoreLexer extends AbstractCharsHandler implements Lexer, Initializi actions = SpringUtils.getBeansAndSort(AbstractLexerAction.class, BorderAction.class); } + /** + * -1.整体替换语句中的某些区域 + * -2.去掉多余的空格 + * -3.利用空格,进行拆分 + * -4.继续拆分带有“.”的单词 + * -5.还原被替换的单词 + */ @Override public List getWords(String text) { Assert.notBlank(text, "text cannot be blank!"); - // 处理字符串 StringBuilder builder = new StringBuilder(text.trim()); LexerContext context = new LexerContext(builder); handle(context, builder, new CursorAction(this)); - // 去掉多余的空格 text = LineUtils.mergeSpaces(context.builder.toString()); - // 利用空格,进行拆分 List words = new ArrayList<>(Arrays.asList(text.split(" "))); - // 继续拆分单词 splitWords(words); - // 还原被替换的单词 restoreWords(words, context.replacedStrs); - return words; } + /** + * -根据弹栈规则,拆分分隔符和单词 + */ @Override public List getSubWords(String text, Character... splitChars) { Assert.notBlank(text, "text cannot be blank!"); - // 处理字符串 StringBuilder builder = new StringBuilder(text.trim()); LexerContext context = new LexerContext(builder, splitChars); handle(context, builder, new CursorAction(borderAction)); - // 校验 Assert.notNull(context.words, "words of context cannot be null!"); - // 继续拆分 List words = new ArrayList<>(); for (String word : context.words) { words.addAll(getWords(word)); @@ -73,8 +74,13 @@ public class CoreLexer extends AbstractCharsHandler implements Lexer, Initializi return words; } + /** + * -继续拆分带有“.”的单词 + * + * @param words + */ public void splitWords(List words) { - for (int index = 0; index < words.size(); index++) {// 如果一个片段中,包含“.”,那么进行更细致的拆分 + for (int index = 0; index < words.size(); index++) { String word = words.get(index); if (word.indexOf(".") > 0 && !LiteralEnum.isDouble(word) && !TypeEnum.isTypeEnd(word)) { List subWords = Arrays.asList(word.replaceAll("\\.", " .").split(" ")); @@ -84,8 +90,14 @@ public class CoreLexer extends AbstractCharsHandler implements Lexer, Initializi } } + /** + * -替换之前被替换的单词 + * + * @param words + * @param replacedStrs + */ public void restoreWords(List words, Map replacedStrs) { - for (int index = 0; index < words.size(); index++) {// 替换回去 + for (int index = 0; index < words.size(); index++) { String str = replacedStrs.get(words.get(index)); if (str != null) { words.set(index, str); -- Gitee From e55ce9fad3b8cccf7c64776c3134bb0ed2c80b0f Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 23 Mar 2021 11:12:57 +0800 Subject: [PATCH 027/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/lexer/action/CursorAction.java | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/CursorAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/CursorAction.java index b128468c..c3af44dd 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/CursorAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/CursorAction.java @@ -1,5 +1,6 @@ package com.sum.spirit.core.lexer.action; +import com.sum.spirit.common.utils.LineUtils; import com.sum.spirit.core.api.CharAction; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; @@ -17,29 +18,42 @@ public class CursorAction implements CharAction { return true; } + /** + * -接续字符和刷新字符,是游标敏感的,用以标记区域的起始位置 + * -先进行弹栈,再刷新startIndex为-1,例如“[”这种情况 + */ @Override public void handle(CharEvent event) { LexerContext context = (LexerContext) event.context; char ch = event.ch; - // 是否连续字符 if ((context.startIndex < 0 && isContinuous(ch)) || isRefreshed(ch)) { context.startIndex = context.index; } - // 真正处理的逻辑 if (action.isTrigger(event)) { action.handle(event); } - // 如果不是连续字符,则重置游标 if (!isContinuous(ch)) { context.startIndex = -1; } } - public boolean isContinuous(char ch) {// 是否连续 - return ch == '@' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_' || ch == '.'; + /** + * -是否接续字符 + * + * @param ch + * @return + */ + public boolean isContinuous(char ch) { + return LineUtils.isLetter(ch) || ch == '@' || ch == '.'; } - public boolean isRefreshed(char ch) {// 是否需要刷新 + /** + * -是否刷新字符 + * + * @param ch + * @return + */ + public boolean isRefreshed(char ch) { return ch == '.'; } -- Gitee From 2d60ea28cf3ff616a51a48ce5405ea4cd14038d0 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 23 Mar 2021 12:45:16 +0800 Subject: [PATCH 028/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/lexer/action/BorderAction.java | 7 ++++--- .../com/sum/spirit/core/lexer/action/RegionAction.java | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java index 67792e8a..07ee63bf 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java @@ -13,14 +13,17 @@ import com.sum.spirit.core.lexer.entity.Region; @Component public class BorderAction extends RegionAction { + /** + * -该类对弹栈行为进行了一定改造,主要对分隔符进行拆分,并将索引直接置为结束 + */ @Override public void pushStack(CharEvent event, List regions, String markName) { LexerContext context = (LexerContext) event.context; StringBuilder builder = context.builder; List splitChars = context.splitChars; - List indexs = new ArrayList<>(); + List indexs = new ArrayList<>(); for (Region region : regions) { char startChar = builder.charAt(region.startIndex); char endChar = builder.charAt(region.endIndex - 1); @@ -30,9 +33,7 @@ public class BorderAction extends RegionAction { } } - // 添加到上下文参数中 context.words = Splitter.splitByIndexsTrimRemain(builder.toString(), indexs); - // 重置索引到结束位置 context.index = builder.length(); } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java index c42272b8..3961b552 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java @@ -31,10 +31,10 @@ public class RegionAction extends AbstractLexerAction { if (ch == '"' || ch == '\'' || ch == '{' || ch == '(' || ch == '[') { return true; - } else if (ch == '<') {// 一般泛型声明都是以大写字母开头的 + } else if (ch == '<') { if (context.startIndex >= 0) { char d = builder.charAt(context.startIndex); - if (d >= 'A' && d <= 'Z') { + if (d >= 'A' && d <= 'Z') {// 一般泛型声明都是以大写字母开头的 return true; } } -- Gitee From e2c8cb850cf3817f246f51c9428262eedd3d73fb Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 23 Mar 2021 14:01:13 +0800 Subject: [PATCH 029/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/common/utils/Lists.java | 17 +++++++++++++++++ .../core/lexer/action/AbstractLexerAction.java | 17 +++++------------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java index c0f8be94..f93565fc 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java @@ -84,6 +84,19 @@ public class Lists { return CollUtil.findOne(collection, item -> matcher.accept(item)); } + public static T findOneByScore(List list, Selector selector) { + Integer finalScore = null; + T finalItem = null; + for (T item : list) { + int score = selector.accept(item); + if (finalScore == null || score > finalScore) { + finalScore = score; + finalItem = item; + } + } + return finalItem; + } + public static List filterStoppable(List list, Filter filter) { List items = new ArrayList<>(); Iterator iterable = list.iterator(); @@ -161,4 +174,8 @@ public class Lists { void accept(int index, T t); } + public static interface Selector { + int accept(T t); + } + } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java index 0991c963..93e9c3fa 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java @@ -6,6 +6,7 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; import com.sum.spirit.common.utils.LineUtils; +import com.sum.spirit.common.utils.Lists; import com.sum.spirit.core.api.CharAction; import com.sum.spirit.core.lexer.entity.Region; @@ -23,18 +24,10 @@ public abstract class AbstractLexerAction implements CharAction { } public Region mergeRegions(List regions) { - Region finalRegion = new Region(-1, -1); - for (Region region : regions) { - Assert.notNull(region, "Region cannot be null!"); - if (finalRegion.startIndex == -1 || region.startIndex < finalRegion.startIndex) { - finalRegion.startIndex = region.startIndex; - } - if (finalRegion.endIndex == -1 || region.endIndex > finalRegion.endIndex) { - finalRegion.endIndex = region.endIndex; - } - } - Assert.isTrue(finalRegion.startIndex != -1 && finalRegion.endIndex != -1, "The index of region cannot be -1!"); - return finalRegion; + Assert.notEmpty(regions, "The regions cannot be empty!"); + Region startRegion = Lists.findOneByScore(regions, region -> 0 - region.startIndex); + Region endRegion = Lists.findOneByScore(regions, region -> region.endIndex); + return new Region(startRegion.startIndex, endRegion.endIndex); } public String replaceRegion(StringBuilder builder, Region region, String markName) { -- Gitee From 6099fc5d7d9ebb15e5705d630c1a03ec153ed797 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 23 Mar 2021 14:48:45 +0800 Subject: [PATCH 030/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java index 24d1a3df..a3492a62 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java @@ -1,6 +1,5 @@ package com.sum.spirit.core.lexer; -import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; import com.sum.spirit.common.utils.LineUtils; @@ -8,7 +7,6 @@ import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.CharsContext; @Component -@DependsOn("springUtils") public class AliasCharsHandler extends AbstractCharsHandler { public String replace(String code, String alias, String className) { -- Gitee From d0a139e70b5f89ee475341e130f1273175a0e138 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 23 Mar 2021 15:06:01 +0800 Subject: [PATCH 031/121] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E5=AD=98=E5=9C=A8=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/lexer/AliasCharsHandler.java | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java index a3492a62..2c11316c 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java @@ -9,6 +9,14 @@ import com.sum.spirit.core.lexer.entity.CharsContext; @Component public class AliasCharsHandler extends AbstractCharsHandler { + /** + * -将别名替换为完整的类名 + * + * @param code + * @param alias + * @param className + * @return + */ public String replace(String code, String alias, String className) { AliasCharsContext context = new AliasCharsContext(); context.builder = new StringBuilder(code); @@ -18,6 +26,9 @@ public class AliasCharsHandler extends AbstractCharsHandler { return context.builder.toString(); } + /** + * -遇到字符串,则跳过,如果当前字符和别名的别名的首字母相同,则触发处理逻辑 + */ @Override public boolean isTrigger(CharEvent event) { AliasCharsContext context = (AliasCharsContext) event.context; @@ -32,19 +43,22 @@ public class AliasCharsHandler extends AbstractCharsHandler { return false; } + /** + * -根据alias的宽度,截取一段字符串,如果相等,则进行替换 + * -注意:这段字符串的前后,不能是连续的字符 + */ @Override public void handle(CharEvent event) { AliasCharsContext context = (AliasCharsContext) event.context; StringBuilder builder = context.builder; String alias = context.alias; String className = context.className; - // 获取结尾的索引 - int idx = context.index + alias.length(); - if (idx <= builder.length()) { - String text = builder.substring(context.index, idx); + int endIndex = context.index + alias.length(); + if (endIndex <= builder.length()) { + String text = builder.substring(context.index, endIndex); if (alias.equals(text)) { - if (!LineUtils.isLetter(builder.charAt(idx))) { - builder.replace(context.index, idx, className); + if (endIndex == builder.length() || !LineUtils.isLetter(builder.charAt(endIndex))) { + builder.replace(context.index, endIndex, className); } } } -- Gitee From 49c508ab5ef67a4de510b8b7e0c3c1348c84ee3a Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 23 Mar 2021 15:18:43 +0800 Subject: [PATCH 032/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/lexer/action/RegionAction.java | 17 +++++++++-------- .../spirit/core/lexer/action/SymbolAction.java | 5 +++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java index 3961b552..dcfe2fca 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java @@ -15,26 +15,26 @@ import com.sum.spirit.core.lexer.entity.Region; @Order(-100) public class RegionAction extends AbstractLexerAction { + /** + * -到达结尾,则直接返回false + * -泛型前缀一般都以大写字母开始 + */ @Override public boolean isTrigger(CharEvent event) { - LexerContext context = (LexerContext) event.context; StringBuilder builder = context.builder; char ch = event.ch; - // 是否已经到达结尾 if (context.index == builder.length() - 1) { return false; - } - // 如果是以下字符,则进行弹栈 - if (ch == '"' || ch == '\'' || ch == '{' || ch == '(' || ch == '[') { + } else if (ch == '"' || ch == '\'' || ch == '{' || ch == '(' || ch == '[') { return true; } else if (ch == '<') { if (context.startIndex >= 0) { char d = builder.charAt(context.startIndex); - if (d >= 'A' && d <= 'Z') {// 一般泛型声明都是以大写字母开头的 + if (d >= 'A' && d <= 'Z') { return true; } } @@ -43,6 +43,9 @@ public class RegionAction extends AbstractLexerAction { return false; } + /** + * str[0] => str [0], String[0] => String[0], String[]{"str", "str"} => String[]{"str", "str"} + */ @Override public void handle(CharEvent event) { @@ -70,12 +73,10 @@ public class RegionAction extends AbstractLexerAction { } else if (ch == '[') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; - // 前缀必须是类型才合并 if (region0 != null && !TypeEnum.isTypePrefix(subRegion(builder, region0))) { region0 = null; } Region region1 = findRegion(builder, context.index, '[', ']'); - // 必须有前缀才解析 Region region2 = null; if (region0 != null) { if (isCharAt(builder, region1.endIndex, '{')) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java index 9c18bb91..33ab6ae0 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java @@ -17,13 +17,15 @@ public class SymbolAction extends AbstractLexerAction { return SymbolEnum.isSymbolChar(event.ch); } + /** + * -尝试拆分双字符和单字符符号 + */ @Override public void handle(CharEvent event) { LexerContext context = (LexerContext) event.context; StringBuilder builder = context.builder; - // 尝试获取两个字符,判断是否双字符符号 if (context.index + 1 < builder.length()) { String str = builder.substring(context.index, context.index + 2); if (SymbolEnum.isDoubleSymbol(str)) { @@ -33,7 +35,6 @@ public class SymbolAction extends AbstractLexerAction { } } - // 尝试获取一个字符,判断是否单字符符号 String str = builder.substring(context.index, context.index + 1); if (SymbolEnum.isSingleSymbol(str)) { Region region = new Region(context.index, context.index + 1); -- Gitee From 89028b1e38cadd63965d7f08a217386aaa9e48a1 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 23 Mar 2021 15:38:06 +0800 Subject: [PATCH 033/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/core/element/utils/StmtFormat.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java index 49925f46..6f30d590 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java @@ -75,15 +75,10 @@ public class StmtFormat { } } else if (nextToken.isSeparator()) { - if ("[".equals(nextToken.toString()) || "(".equals(nextToken.toString()) || "<".equals(nextToken.toString())) { - tokens.remove(index); - return; - - } else if ("]".equals(nextToken.toString()) || ")".equals(nextToken.toString()) || ">".equals(nextToken.toString())) { - tokens.remove(index); - return; - - } else if (",".equals(nextToken.toString()) || ";".equals(nextToken.toString())) { + if ("[".equals(nextToken.toString()) || "]".equals(nextToken.toString()) || // + "(".equals(nextToken.toString()) || ")".equals(nextToken.toString()) || // + "<".equals(nextToken.toString()) || ">".equals(nextToken.toString()) || // + ",".equals(nextToken.toString()) || ";".equals(nextToken.toString())) { tokens.remove(index); return; } -- Gitee From 91213dea180228dba2c5a6b2c94e2bad519387b7 Mon Sep 17 00:00:00 2001 From: chenT Date: Tue, 23 Mar 2021 21:18:36 +0800 Subject: [PATCH 034/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/element/ElementBuilderImpl.java | 19 ++- .../core/element/action/SyntaxRecognizer.java | 147 ++++++++++++++++++ .../core/element/entity/SyntaxTree.java | 145 ----------------- 3 files changed, 156 insertions(+), 155 deletions(-) create mode 100644 spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java index ffe75c37..1c1e3cd4 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java @@ -11,6 +11,7 @@ import com.sum.spirit.core.api.Lexer; import com.sum.spirit.core.api.SemanticParser; import com.sum.spirit.core.api.TreeBuilder; import com.sum.spirit.core.element.action.LineChecker; +import com.sum.spirit.core.element.action.SyntaxRecognizer; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Line; import com.sum.spirit.core.element.entity.Modifiers; @@ -30,6 +31,8 @@ public class ElementBuilderImpl implements ElementBuilder { @Autowired public SemanticParser parser; @Autowired + public SyntaxRecognizer recognizer; + @Autowired public TreeBuilder builder; @Override @@ -50,17 +53,13 @@ public class ElementBuilderImpl implements ElementBuilder { Modifiers modifiers = new Modifiers(tokens); // 4.语句 Statement statement = new Statement(tokens); - // 5.语法枚举 - SyntaxEnum syntax = SyntaxTree.getSimpleSyntax(tokens); - // 6.构建语法树 - SyntaxTree syntaxTree = null; - if (syntax == null) { - syntaxTree = builder.buildTree(statement); - syntax = syntaxTree.getSyntax(); - } - // 7.创建元素 + // 5.分析语法 + SyntaxEnum syntax = recognizer.getSimpleSyntax(tokens); + SyntaxTree syntaxTree = recognizer.needBuildTree(syntax) ? builder.buildTree(statement) : null; + syntax = syntax == null ? recognizer.getSyntax(syntaxTree) : syntax; + // 6.创建元素 Element element = new Element(line, modifiers, statement, syntaxTree, syntax); - // 8.返回元素 + // 7.返回元素 return element; } catch (Exception e) { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java new file mode 100644 index 00000000..7e434300 --- /dev/null +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java @@ -0,0 +1,147 @@ +package com.sum.spirit.core.element.action; + +import java.util.List; + +import org.springframework.stereotype.Component; + +import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.enums.KeywordEnum; +import com.sum.spirit.common.enums.SymbolEnum; +import com.sum.spirit.common.enums.SyntaxEnum; +import com.sum.spirit.core.element.entity.Node; +import com.sum.spirit.core.element.entity.SyntaxTree; +import com.sum.spirit.core.element.entity.Token; + +import cn.hutool.core.lang.Assert; + +@Component +public class SyntaxRecognizer { + + public SyntaxEnum getSimpleSyntax(List tokens) { + + Assert.notEmpty(tokens, "The tokens cannot be empty!"); + + Token firstToken = tokens.size() >= 1 ? tokens.get(0) : null; + Token secondToken = tokens.size() >= 2 ? tokens.get(1) : null; + Token thirdToken = tokens.size() >= 3 ? tokens.get(2) : null; + + // keyword + if (KeywordEnum.isStruct(firstToken.toString()) || KeywordEnum.isLine(firstToken.toString())) { + return SyntaxEnum.valueOf(firstToken.toString().toUpperCase()); + } + // end + if (tokens.size() == 1 && "}".equals(firstToken.toString())) { + return SyntaxEnum.END; + } + // annotation + if (tokens.size() == 1 && firstToken.isAnnotation()) { + return SyntaxEnum.ANNOTATION; + } + + // 如果是for关键词 + if (KeywordEnum.FOR.value.equals(firstToken.toString())) { + if (secondToken.isSubexpress()) {// for (i=0; i<10; i++) { + return SyntaxEnum.FOR; + } + if (KeywordEnum.IN.value.equals(thirdToken.toString())) {// for ? in ? { + return SyntaxEnum.FOR_IN; + } + throw new RuntimeException("Unknown syntax!"); + } + + // 如果是“}”开始 + if (SymbolEnum.RIGHT_CURLY_BRACKET.value.equals(firstToken.toString())) { + if (KeywordEnum.ELSE.value.equals(secondToken.toString())) { + if (thirdToken != null && KeywordEnum.IF.value.equals(thirdToken.toString())) {// } else if ? { + return SyntaxEnum.ELSE_IF; + } else {// } else { + return SyntaxEnum.ELSE; + } + + } else if (KeywordEnum.CATCH.value.equals(secondToken.toString())) {// } catch Exception x { + return SyntaxEnum.CATCH; + + } else if (KeywordEnum.FINALLY.value.equals(secondToken.toString())) {// } finally { + return SyntaxEnum.FINALLY; + } + throw new RuntimeException("Unknown syntax!"); + } + + return null; + } + + public boolean needBuildTree(SyntaxEnum syntax) { + return syntax == null || !KeywordEnum.isStruct(syntax.toString().toLowerCase()); + } + + public SyntaxEnum getSyntax(SyntaxTree syntaxTree) { + SyntaxEnum syntax = null; + if (syntaxTree.nodes.size() == 1) { + syntax = getSyntaxByOneNode(syntaxTree); + + } else if (syntaxTree.nodes.size() == 2) { + syntax = getSyntaxByOneNode(syntaxTree); + } + Assert.notNull(syntax, "The syntax cannot be null!"); + return syntax; + } + + public SyntaxEnum getSyntaxByOneNode(SyntaxTree syntaxTree) { + + Node firstNode = syntaxTree.nodes.get(0); + Token firstToken = firstNode.token; + + // 如果只有一个节点,可能是方法调用 + if (firstToken.isLocalMethod()) { + String memberName = firstToken.attr(AttributeEnum.MEMBER_NAME); + if (KeywordEnum.SUPER.value.equals(memberName)) { + return SyntaxEnum.SUPER; + + } else if (KeywordEnum.THIS.value.equals(memberName)) { + return SyntaxEnum.THIS; + } + return SyntaxEnum.INVOKE; + } + + // 通过抽象语法树进行推导 + if (firstToken.isType()) { + Token nextToken = firstNode.next.token; + if (nextToken.isVariable()) { // String text + return SyntaxEnum.DECLARE; + + } else if (nextToken.isLocalMethod()) { // String test() + return SyntaxEnum.DECLARE_FUNC; + } + + } else if (firstToken.isAssign()) { + Token prevToken = firstNode.prev.token; + if (prevToken.isType()) {// String text = "abc" + return SyntaxEnum.DECLARE_ASSIGN; + + } else if (prevToken.isVariable()) {// text = "abc" + return SyntaxEnum.ASSIGN; + + } else if (prevToken.isVisitField()) {// var.text = "abc" + return SyntaxEnum.FIELD_ASSIGN; + } + + } else if (firstToken.isVisitMethod()) {// list.get(0) + return SyntaxEnum.INVOKE; + } + + return null; + } + + public SyntaxEnum getSyntaxByTwoNodes(SyntaxTree syntaxTree) { + Node firstNode = syntaxTree.nodes.get(0); + Token firstToken = firstNode.token; + if (firstToken.isType()) { + Token nextToken = firstNode.next.token; + if (nextToken.isLocalMethod()) { + return SyntaxEnum.DECLARE_FUNC; + } + } + return null; + } + +} diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java index 7c4172ef..36f73250 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java @@ -2,11 +2,6 @@ package com.sum.spirit.core.element.entity; import java.util.List; -import com.sum.spirit.common.enums.AttributeEnum; -import com.sum.spirit.common.enums.KeywordEnum; -import com.sum.spirit.common.enums.SymbolEnum; -import com.sum.spirit.common.enums.SyntaxEnum; - public class SyntaxTree { public List nodes; @@ -15,146 +10,6 @@ public class SyntaxTree { this.nodes = nodes; } - public static SyntaxEnum getSimpleSyntax(List tokens) { - Token first = tokens.get(0); - // keyword - if (KeywordEnum.isStruct(first.toString())) { - return SyntaxEnum.valueOf(first.toString().toUpperCase()); - } - // end - if (tokens.size() == 1 && "}".equals(first.toString())) { - return SyntaxEnum.END; - } - // annotation - if (tokens.size() == 1 && first.isAnnotation()) { - return SyntaxEnum.ANNOTATION; - } - // unknown - return null; - } - - public SyntaxEnum getSyntax() { - SyntaxEnum syntax = getLineSyntax(); - if (syntax != null) { - return syntax; - } - syntax = getSyntaxByOneNode(); - if (syntax != null) { - return syntax; - } - syntax = getSyntaxByTwoNodes(); - if (syntax != null) { - return syntax; - } - syntax = getSyntaxByThreeNodes(); - if (syntax != null) { - return syntax; - } - throw new RuntimeException("Unknown syntax!"); - } - - public SyntaxEnum getLineSyntax() { - Node firstNode = nodes.get(0); - Token firstToken = firstNode.token; - // 如果是行级别关键字,则直接返回语法枚举 - if (!firstNode.canSplit() && KeywordEnum.isLine(firstToken.toString())) { - return SyntaxEnum.valueOf(firstToken.toString().toUpperCase()); - } - return null; - } - - public SyntaxEnum getSyntaxByOneNode() { - if (nodes.size() != 1) { - return null; - } - - Node firstNode = nodes.get(0); - Token firstToken = firstNode.token; - - // 如果只有一个节点,可能是方法调用 - if (firstToken.isLocalMethod()) { - String memberName = firstToken.attr(AttributeEnum.MEMBER_NAME); - if (KeywordEnum.SUPER.value.equals(memberName)) { - return SyntaxEnum.SUPER; - } else if (KeywordEnum.THIS.value.equals(memberName)) { - return SyntaxEnum.THIS; - } - return SyntaxEnum.INVOKE; - } - - // 通过抽象语法树进行推导 - if (firstToken.isType()) { - Token nextToken = firstNode.next.token; - if (nextToken.isVariable()) { // String text - return SyntaxEnum.DECLARE; - } else if (nextToken.isLocalMethod()) { // String test() - return SyntaxEnum.DECLARE_FUNC; - } - } else if (firstToken.isAssign()) { - Token prevToken = firstNode.prev.token; - if (prevToken.isType()) {// String text = "abc" - return SyntaxEnum.DECLARE_ASSIGN; - } else if (prevToken.isVariable()) {// text = "abc" - return SyntaxEnum.ASSIGN; - } else if (prevToken.isVisitField()) {// var.text = "abc" - return SyntaxEnum.FIELD_ASSIGN; - } - } else if (firstToken.isVisitMethod()) {// list.get(0) - return SyntaxEnum.INVOKE; - } - - throw new RuntimeException("Unknown syntax!"); - } - - public SyntaxEnum getSyntaxByTwoNodes() { - if (nodes.size() != 2) { - return null; - } - - Node firstNode = nodes.get(0); - Token firstToken = firstNode.token; - if (firstToken.isType()) { - Token nextToken = firstNode.next.token; - if (nextToken.isLocalMethod()) { - return SyntaxEnum.DECLARE_FUNC; - } - } - - throw new RuntimeException("Unknown syntax!"); - } - - public SyntaxEnum getSyntaxByThreeNodes() { - Token firstToken = nodes.get(0).token; - Token secondToken = nodes.get(1).token; - Token thirdToken = nodes.get(2).token; - - if (KeywordEnum.FOR.value.equals(firstToken.toString())) { - if (secondToken.isSubexpress()) { - return SyntaxEnum.FOR;// for (i=0; i<10; i++) { - } - if (KeywordEnum.IN.value.equals(thirdToken.toString())) { - return SyntaxEnum.FOR_IN;// for ? in ? { - } - throw new RuntimeException("Unknown syntax!"); - } - - if (SymbolEnum.RIGHT_CURLY_BRACKET.value.equals(firstToken.toString())) { - if (KeywordEnum.ELSE.value.equals(secondToken.toString())) { - if (KeywordEnum.IF.value.equals(thirdToken.toString())) {// } else if ? { - return SyntaxEnum.ELSE_IF; - } else { - return SyntaxEnum.ELSE;// } else { - } - } else if (KeywordEnum.CATCH.value.equals(secondToken.toString())) {// } catch Exception x { - return SyntaxEnum.CATCH; - } else if (KeywordEnum.FINALLY.value.equals(secondToken.toString())) {// } finally { - return SyntaxEnum.FINALLY; - } - } - - throw new RuntimeException("Unknown syntax!"); - } - @Override public String toString() { throw new RuntimeException("The method toString() should not be called"); -- Gitee From cb2640069131c8b78bd77b139be4dfa6275bb12f Mon Sep 17 00:00:00 2001 From: chenT Date: Tue, 23 Mar 2021 21:37:28 +0800 Subject: [PATCH 035/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/core/element/action/SyntaxRecognizer.java | 7 +++---- .../com/sum/spirit/core/element/entity/SyntaxTree.java | 5 ----- .../java/com/sum/spirit/core/lexer/test/SyntaxTest.java | 6 ++++-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java index 7e434300..7d2cd411 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java @@ -78,9 +78,8 @@ public class SyntaxRecognizer { SyntaxEnum syntax = null; if (syntaxTree.nodes.size() == 1) { syntax = getSyntaxByOneNode(syntaxTree); - - } else if (syntaxTree.nodes.size() == 2) { - syntax = getSyntaxByOneNode(syntaxTree); + } else { + syntax = getSyntaxByNodes(syntaxTree); } Assert.notNull(syntax, "The syntax cannot be null!"); return syntax; @@ -132,7 +131,7 @@ public class SyntaxRecognizer { return null; } - public SyntaxEnum getSyntaxByTwoNodes(SyntaxTree syntaxTree) { + public SyntaxEnum getSyntaxByNodes(SyntaxTree syntaxTree) { Node firstNode = syntaxTree.nodes.get(0); Token firstToken = firstNode.token; if (firstToken.isType()) { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java index 36f73250..c6a78eac 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxTree.java @@ -10,9 +10,4 @@ public class SyntaxTree { this.nodes = nodes; } - @Override - public String toString() { - throw new RuntimeException("The method toString() should not be called"); - } - } diff --git a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SyntaxTest.java b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SyntaxTest.java index 04e9a75e..9226a1bf 100644 --- a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SyntaxTest.java +++ b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SyntaxTest.java @@ -151,13 +151,15 @@ public class SyntaxTest { @Test @DisplayName("DECLARE_FUNC") public void test0010() { - String text = "String call() {"; + String text = "String call() throws Exception {"; Element element = builder.build(text); assertTrue(element.isDeclareFunc()); - assertTrue(element.size() == 3); + assertTrue(element.size() == 5); int count = 0; assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "String"); assertTypeAndValue(element.get(count++), TokenTypeEnum.LOCAL_METHOD, "call()"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.KEYWORD, "throws"); + assertTypeAndValue(element.get(count++), TokenTypeEnum.TYPE, "Exception"); assertTypeAndValue(element.get(count++), TokenTypeEnum.SEPARATOR, "{"); } -- Gitee From 8df2db7102e52f55db9e551ec185645fea66ab92 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Wed, 24 Mar 2021 13:17:21 +0800 Subject: [PATCH 036/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/element/action/SyntaxRecognizer.java | 82 ++++++++++--------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java index 7d2cd411..f01a7bc4 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java @@ -21,24 +21,44 @@ public class SyntaxRecognizer { Assert.notEmpty(tokens, "The tokens cannot be empty!"); - Token firstToken = tokens.size() >= 1 ? tokens.get(0) : null; + Token firstToken = tokens.get(0); Token secondToken = tokens.size() >= 2 ? tokens.get(1) : null; Token thirdToken = tokens.size() >= 3 ? tokens.get(2) : null; - // keyword - if (KeywordEnum.isStruct(firstToken.toString()) || KeywordEnum.isLine(firstToken.toString())) { - return SyntaxEnum.valueOf(firstToken.toString().toUpperCase()); - } - // end + // END if (tokens.size() == 1 && "}".equals(firstToken.toString())) { return SyntaxEnum.END; } - // annotation + + // ANNOTATION if (tokens.size() == 1 && firstToken.isAnnotation()) { return SyntaxEnum.ANNOTATION; } - // 如果是for关键词 + // KEYWORDS + if (KeywordEnum.isStruct(firstToken.toString()) || KeywordEnum.isLine(firstToken.toString())) { + return SyntaxEnum.valueOf(firstToken.toString().toUpperCase()); + } + + // SUPER / THIS + if (firstToken.isLocalMethod()) { + String memberName = firstToken.attr(AttributeEnum.MEMBER_NAME); + if (KeywordEnum.SUPER.value.equals(memberName)) { + return SyntaxEnum.SUPER; + + } else if (KeywordEnum.THIS.value.equals(memberName)) { + return SyntaxEnum.THIS; + } + } + + // DECLARE_FUNC + if (firstToken.isType()) { + if (secondToken != null && secondToken.isLocalMethod()) { + return SyntaxEnum.DECLARE_FUNC; + } + } + + // FOR / FOR_IN if (KeywordEnum.FOR.value.equals(firstToken.toString())) { if (secondToken.isSubexpress()) {// for (i=0; i<10; i++) { return SyntaxEnum.FOR; @@ -49,7 +69,7 @@ public class SyntaxRecognizer { throw new RuntimeException("Unknown syntax!"); } - // 如果是“}”开始 + // ELSE / ELSE_IF / CATCH / FINALLY if (SymbolEnum.RIGHT_CURLY_BRACKET.value.equals(firstToken.toString())) { if (KeywordEnum.ELSE.value.equals(secondToken.toString())) { if (thirdToken != null && KeywordEnum.IF.value.equals(thirdToken.toString())) {// } else if ? { @@ -71,15 +91,22 @@ public class SyntaxRecognizer { } public boolean needBuildTree(SyntaxEnum syntax) { - return syntax == null || !KeywordEnum.isStruct(syntax.toString().toLowerCase()); + if (syntax == null) { + return true; + } else { + if (KeywordEnum.isStruct(syntax.toString().toLowerCase())) { + return false; + } else if (syntax == SyntaxEnum.DECLARE_FUNC) { + return false; + } + return true; + } } public SyntaxEnum getSyntax(SyntaxTree syntaxTree) { SyntaxEnum syntax = null; if (syntaxTree.nodes.size() == 1) { syntax = getSyntaxByOneNode(syntaxTree); - } else { - syntax = getSyntaxByNodes(syntaxTree); } Assert.notNull(syntax, "The syntax cannot be null!"); return syntax; @@ -90,26 +117,10 @@ public class SyntaxRecognizer { Node firstNode = syntaxTree.nodes.get(0); Token firstToken = firstNode.token; - // 如果只有一个节点,可能是方法调用 - if (firstToken.isLocalMethod()) { - String memberName = firstToken.attr(AttributeEnum.MEMBER_NAME); - if (KeywordEnum.SUPER.value.equals(memberName)) { - return SyntaxEnum.SUPER; - - } else if (KeywordEnum.THIS.value.equals(memberName)) { - return SyntaxEnum.THIS; - } - return SyntaxEnum.INVOKE; - } - - // 通过抽象语法树进行推导 if (firstToken.isType()) { Token nextToken = firstNode.next.token; if (nextToken.isVariable()) { // String text return SyntaxEnum.DECLARE; - - } else if (nextToken.isLocalMethod()) { // String test() - return SyntaxEnum.DECLARE_FUNC; } } else if (firstToken.isAssign()) { @@ -124,6 +135,9 @@ public class SyntaxRecognizer { return SyntaxEnum.FIELD_ASSIGN; } + } else if (firstToken.isLocalMethod()) {// doSomething() + return SyntaxEnum.INVOKE; + } else if (firstToken.isVisitMethod()) {// list.get(0) return SyntaxEnum.INVOKE; } @@ -131,16 +145,4 @@ public class SyntaxRecognizer { return null; } - public SyntaxEnum getSyntaxByNodes(SyntaxTree syntaxTree) { - Node firstNode = syntaxTree.nodes.get(0); - Token firstToken = firstNode.token; - if (firstToken.isType()) { - Token nextToken = firstNode.next.token; - if (nextToken.isLocalMethod()) { - return SyntaxEnum.DECLARE_FUNC; - } - } - return null; - } - } -- Gitee From 123ab5ecae2227bc6cc9db3ae84f78a0f32f9566 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Wed, 24 Mar 2021 14:44:26 +0800 Subject: [PATCH 037/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/element/ElementBuilderImpl.java | 9 +- .../core/element/action/SyntaxRecognizer.java | 108 ++++++++++-------- 2 files changed, 66 insertions(+), 51 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java index 1c1e3cd4..c98ba611 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java @@ -9,7 +9,6 @@ import com.sum.spirit.common.enums.SyntaxEnum; import com.sum.spirit.core.api.ElementBuilder; import com.sum.spirit.core.api.Lexer; import com.sum.spirit.core.api.SemanticParser; -import com.sum.spirit.core.api.TreeBuilder; import com.sum.spirit.core.element.action.LineChecker; import com.sum.spirit.core.element.action.SyntaxRecognizer; import com.sum.spirit.core.element.entity.Element; @@ -32,8 +31,6 @@ public class ElementBuilderImpl implements ElementBuilder { public SemanticParser parser; @Autowired public SyntaxRecognizer recognizer; - @Autowired - public TreeBuilder builder; @Override public Element build(String text) { @@ -54,9 +51,9 @@ public class ElementBuilderImpl implements ElementBuilder { // 4.语句 Statement statement = new Statement(tokens); // 5.分析语法 - SyntaxEnum syntax = recognizer.getSimpleSyntax(tokens); - SyntaxTree syntaxTree = recognizer.needBuildTree(syntax) ? builder.buildTree(statement) : null; - syntax = syntax == null ? recognizer.getSyntax(syntaxTree) : syntax; + Object[] result = recognizer.parseSyntax(tokens, statement); + SyntaxEnum syntax = (SyntaxEnum) result[0]; + SyntaxTree syntaxTree = (SyntaxTree) result[1]; // 6.创建元素 Element element = new Element(line, modifiers, statement, syntaxTree, syntax); // 7.返回元素 diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java index f01a7bc4..3373142a 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java @@ -2,13 +2,16 @@ package com.sum.spirit.core.element.action; import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.SyntaxEnum; +import com.sum.spirit.core.api.TreeBuilder; import com.sum.spirit.core.element.entity.Node; +import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.SyntaxTree; import com.sum.spirit.core.element.entity.Token; @@ -17,29 +20,78 @@ import cn.hutool.core.lang.Assert; @Component public class SyntaxRecognizer { - public SyntaxEnum getSimpleSyntax(List tokens) { - + @Autowired + public TreeBuilder builder; + + /** + * 1.能够不通过语法树获取语法,且后续功能不需要语法树 + * 2.能够不通过语法树获取语法,但后续功能需要语法树 + * 3.必须通过语法树获取语法 + * + * @param tokens + * @param statement + * @return + */ + public Object[] parseSyntax(List tokens, Statement statement) { Assert.notEmpty(tokens, "The tokens cannot be empty!"); + SyntaxEnum syntax = getSyntaxWithoutTree(tokens); + SyntaxTree syntaxTree = null; + if (syntax == null) { + syntax = getSyntaxWithTree(tokens); + if (syntax != null) { + syntaxTree = builder.buildTree(statement); + } else { + syntaxTree = builder.buildTree(statement); + syntax = getSyntaxByTree(syntaxTree); + } + } + Assert.notNull(syntax, "The syntax cannot be null!"); + return new Object[] { syntax, syntaxTree }; + } + public SyntaxEnum getSyntaxWithoutTree(List tokens) { Token firstToken = tokens.get(0); Token secondToken = tokens.size() >= 2 ? tokens.get(1) : null; - Token thirdToken = tokens.size() >= 3 ? tokens.get(2) : null; - // END if (tokens.size() == 1 && "}".equals(firstToken.toString())) { return SyntaxEnum.END; } - // ANNOTATION if (tokens.size() == 1 && firstToken.isAnnotation()) { return SyntaxEnum.ANNOTATION; } - - // KEYWORDS - if (KeywordEnum.isStruct(firstToken.toString()) || KeywordEnum.isLine(firstToken.toString())) { + // STRUCT + if (KeywordEnum.isStruct(firstToken.toString())) { return SyntaxEnum.valueOf(firstToken.toString().toUpperCase()); } + // DECLARE_FUNC + if (firstToken.isType()) { + if (secondToken != null && secondToken.isLocalMethod()) { + return SyntaxEnum.DECLARE_FUNC; + } + } + // CATCH / FINALLY + if (SymbolEnum.RIGHT_CURLY_BRACKET.value.equals(firstToken.toString())) { + if (secondToken != null) { + if (KeywordEnum.CATCH.value.equals(secondToken.toString())) {// } catch Exception x { + return SyntaxEnum.CATCH; + + } else if (KeywordEnum.FINALLY.value.equals(secondToken.toString())) {// } finally { + return SyntaxEnum.FINALLY; + } + } + } + return null; + } + public SyntaxEnum getSyntaxWithTree(List tokens) { + Token firstToken = tokens.get(0); + Token secondToken = tokens.size() >= 2 ? tokens.get(1) : null; + Token thirdToken = tokens.size() >= 3 ? tokens.get(2) : null; + // LINE + if (KeywordEnum.isLine(firstToken.toString())) { + return SyntaxEnum.valueOf(firstToken.toString().toUpperCase()); + } // SUPER / THIS if (firstToken.isLocalMethod()) { String memberName = firstToken.attr(AttributeEnum.MEMBER_NAME); @@ -50,14 +102,6 @@ public class SyntaxRecognizer { return SyntaxEnum.THIS; } } - - // DECLARE_FUNC - if (firstToken.isType()) { - if (secondToken != null && secondToken.isLocalMethod()) { - return SyntaxEnum.DECLARE_FUNC; - } - } - // FOR / FOR_IN if (KeywordEnum.FOR.value.equals(firstToken.toString())) { if (secondToken.isSubexpress()) {// for (i=0; i<10; i++) { @@ -68,8 +112,7 @@ public class SyntaxRecognizer { } throw new RuntimeException("Unknown syntax!"); } - - // ELSE / ELSE_IF / CATCH / FINALLY + // ELSE / ELSE_IF if (SymbolEnum.RIGHT_CURLY_BRACKET.value.equals(firstToken.toString())) { if (KeywordEnum.ELSE.value.equals(secondToken.toString())) { if (thirdToken != null && KeywordEnum.IF.value.equals(thirdToken.toString())) {// } else if ? { @@ -77,39 +120,14 @@ public class SyntaxRecognizer { } else {// } else { return SyntaxEnum.ELSE; } - - } else if (KeywordEnum.CATCH.value.equals(secondToken.toString())) {// } catch Exception x { - return SyntaxEnum.CATCH; - - } else if (KeywordEnum.FINALLY.value.equals(secondToken.toString())) {// } finally { - return SyntaxEnum.FINALLY; } throw new RuntimeException("Unknown syntax!"); } - return null; } - public boolean needBuildTree(SyntaxEnum syntax) { - if (syntax == null) { - return true; - } else { - if (KeywordEnum.isStruct(syntax.toString().toLowerCase())) { - return false; - } else if (syntax == SyntaxEnum.DECLARE_FUNC) { - return false; - } - return true; - } - } - - public SyntaxEnum getSyntax(SyntaxTree syntaxTree) { - SyntaxEnum syntax = null; - if (syntaxTree.nodes.size() == 1) { - syntax = getSyntaxByOneNode(syntaxTree); - } - Assert.notNull(syntax, "The syntax cannot be null!"); - return syntax; + public SyntaxEnum getSyntaxByTree(SyntaxTree syntaxTree) { + return syntaxTree.nodes.size() == 1 ? getSyntaxByOneNode(syntaxTree) : null; } public SyntaxEnum getSyntaxByOneNode(SyntaxTree syntaxTree) { -- Gitee From 7ae073d61be4e9b54299de9fdd4a525784b9c46e Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Wed, 24 Mar 2021 14:53:50 +0800 Subject: [PATCH 038/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/element/action/SyntaxRecognizer.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java index 3373142a..a14c9048 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java @@ -52,6 +52,7 @@ public class SyntaxRecognizer { public SyntaxEnum getSyntaxWithoutTree(List tokens) { Token firstToken = tokens.get(0); Token secondToken = tokens.size() >= 2 ? tokens.get(1) : null; + Token thirdToken = tokens.size() >= 3 ? tokens.get(2) : null; // END if (tokens.size() == 1 && "}".equals(firstToken.toString())) { return SyntaxEnum.END; @@ -70,15 +71,18 @@ public class SyntaxRecognizer { return SyntaxEnum.DECLARE_FUNC; } } - // CATCH / FINALLY + // ELSE / CATCH / FINALLY if (SymbolEnum.RIGHT_CURLY_BRACKET.value.equals(firstToken.toString())) { - if (secondToken != null) { - if (KeywordEnum.CATCH.value.equals(secondToken.toString())) {// } catch Exception x { - return SyntaxEnum.CATCH; - - } else if (KeywordEnum.FINALLY.value.equals(secondToken.toString())) {// } finally { - return SyntaxEnum.FINALLY; + if (KeywordEnum.ELSE.value.equals(secondToken.toString())) {// } else { + if (SymbolEnum.LEFT_CURLY_BRACKET.value.equals(thirdToken.toString())) { + return SyntaxEnum.ELSE; } + + } else if (KeywordEnum.CATCH.value.equals(secondToken.toString())) {// } catch Exception x { + return SyntaxEnum.CATCH; + + } else if (KeywordEnum.FINALLY.value.equals(secondToken.toString())) {// } finally { + return SyntaxEnum.FINALLY; } } return null; @@ -112,13 +116,11 @@ public class SyntaxRecognizer { } throw new RuntimeException("Unknown syntax!"); } - // ELSE / ELSE_IF + // ELSE_IF if (SymbolEnum.RIGHT_CURLY_BRACKET.value.equals(firstToken.toString())) { if (KeywordEnum.ELSE.value.equals(secondToken.toString())) { - if (thirdToken != null && KeywordEnum.IF.value.equals(thirdToken.toString())) {// } else if ? { + if (KeywordEnum.IF.value.equals(thirdToken.toString())) {// } else if ? { return SyntaxEnum.ELSE_IF; - } else {// } else { - return SyntaxEnum.ELSE; } } throw new RuntimeException("Unknown syntax!"); -- Gitee From 41f3b157b10a671842637c3ba1a6fd360b4e558f Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Wed, 24 Mar 2021 14:58:19 +0800 Subject: [PATCH 039/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/element/ElementBuilderImpl.java | 2 +- .../main/java/com/sum/spirit/core/element/entity/Element.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java index c98ba611..08c41db3 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java @@ -55,7 +55,7 @@ public class ElementBuilderImpl implements ElementBuilder { SyntaxEnum syntax = (SyntaxEnum) result[0]; SyntaxTree syntaxTree = (SyntaxTree) result[1]; // 6.创建元素 - Element element = new Element(line, modifiers, statement, syntaxTree, syntax); + Element element = new Element(line, modifiers, statement, syntax, syntaxTree); // 7.返回元素 return element; diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Element.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Element.java index c3344268..32d196b7 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Element.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Element.java @@ -14,7 +14,7 @@ public class Element extends Syntactic { public SyntaxTree syntaxTree; public List children = new ArrayList<>(); - public Element(Line line, Modifiers modifiers, Statement statement, SyntaxTree syntaxTree, SyntaxEnum syntax) { + public Element(Line line, Modifiers modifiers, Statement statement, SyntaxEnum syntax, SyntaxTree syntaxTree) { super(syntax, statement); this.line = line; this.modifiers = modifiers; -- Gitee From 97121c9652ad6490f461c2845719055861ef065d Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 9 Apr 2021 09:55:47 +0800 Subject: [PATCH 040/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/common/constants/Constants.java | 2 -- .../java/com/sum/spirit/common/utils/ConfigUtils.java | 4 ---- .../com/sum/spirit/core/compile/ClassVisiter.java | 11 +++-------- .../src/main/resources/application.properties | 5 +---- 4 files changed, 4 insertions(+), 18 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/constants/Constants.java b/spirit-common/src/main/java/com/sum/spirit/common/constants/Constants.java index 9c7f7a54..a8afd79b 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/constants/Constants.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/constants/Constants.java @@ -10,10 +10,8 @@ public class Constants { public static final String FILENAME_EXTENSION_KEY = "spirit.compile.file.extension"; public static final String DEBUG_KEY = "spirit.compile.debug"; - public static final String SYNTAX_CHECK_KEY = "spirit.compile.syntax.check"; public static final String DEFAULT_FILENAME_EXTENSION = "sp"; public static final boolean DEFAULT_DEBUG = true; - public static final boolean DEFAULT_SYNTAX_CHECK = true; } diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/ConfigUtils.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/ConfigUtils.java index 0a019141..60ef713c 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/ConfigUtils.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/ConfigUtils.java @@ -56,8 +56,4 @@ public class ConfigUtils implements EnvironmentAware { return ConfigUtils.getProperty(Constants.DEBUG_KEY, Constants.DEFAULT_DEBUG); } - public static boolean isSyntaxCheck() { - return ConfigUtils.getProperty(Constants.SYNTAX_CHECK_KEY, Constants.DEFAULT_SYNTAX_CHECK); - } - } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java index 49b5015c..eea8b765 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java @@ -6,7 +6,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.TokenTypeEnum; -import com.sum.spirit.common.utils.ConfigUtils; import com.sum.spirit.common.utils.Lists; import com.sum.spirit.common.utils.ObjectUtils; import com.sum.spirit.common.utils.SpringUtils; @@ -166,13 +165,9 @@ public class ClassVisiter { } } - if (element.isReturn()) { - if (index != elements.size() - 1) { // 语法校验 - if (ConfigUtils.isSyntaxCheck()) { - throw new RuntimeException("The method body does not end with a return statement!"); - } - } - break;// 提前结束 + // 如果return语句后面还有语句,则抛出异常 + if (element.isReturn() && index != elements.size() - 1) { + throw new RuntimeException("The method body does not end with a return statement!"); } // 遍历子节点 diff --git a/spirit-starter/spirit-starter-kit/src/main/resources/application.properties b/spirit-starter/spirit-starter-kit/src/main/resources/application.properties index 0c8810a3..900fe3a6 100644 --- a/spirit-starter/spirit-starter-kit/src/main/resources/application.properties +++ b/spirit-starter/spirit-starter-kit/src/main/resources/application.properties @@ -1,5 +1,2 @@ spring.profiles.active=kit -server.port=8729 -spirit.compile.auto.run=false -spirit.compile.debug=true -spirit.compile.syntax.check=false +server.port=8729 \ No newline at end of file -- Gitee From 08a2b4a6ce0e76c558bf66c51c3f54762a66074a Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 9 Apr 2021 10:03:35 +0800 Subject: [PATCH 041/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/sum/spirit/core/lexer/CoreLexer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java index eb92e2c4..73afd37c 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java @@ -69,7 +69,11 @@ public class CoreLexer extends AbstractCharsHandler implements Lexer, Initializi Assert.notNull(context.words, "words of context cannot be null!"); List words = new ArrayList<>(); for (String word : context.words) { - words.addAll(getWords(word)); + if (word.length() == 1) { + words.add(word); + } else { + words.addAll(getWords(word)); + } } return words; } -- Gitee From 601098b49d9269ea1b9c48708757bcad1b592021 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 9 Apr 2021 11:44:20 +0800 Subject: [PATCH 042/121] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E7=94=9F=E6=88=90=E6=96=87=E4=BB=B6=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E7=9B=B4=E6=8E=A5=E5=B0=86=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E5=8C=85=E6=94=BE=E5=9C=A8=E8=BE=93=E5=87=BA=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=B9=E4=B8=8B=EF=BC=8C=E5=8F=91=E5=B8=832.0.48=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 13 ++- spirit-common/pom.xml | 2 +- .../com/sum/spirit/common/utils/Lists.java | 2 +- .../{FileURLUtils.java => URLFileUtils.java} | 2 +- .../spirit/{common/utils => lib}/Maps.java | 33 +------- spirit-core/pom.xml | 2 +- spirit-core/spirit-core-class/pom.xml | 2 +- spirit-core/spirit-core-compile/pom.xml | 2 +- .../core/compile/AbstractURLClassLoader.java | 13 ++- .../spirit/core/compile/AppClassLoader.java | 4 +- spirit-core/spirit-core-element/pom.xml | 2 +- spirit-core/spirit-core-lexer/pom.xml | 2 +- spirit-output/pom.xml | 2 +- spirit-output/spirit-output-java/pom.xml | 2 +- .../output/java/action/CommonAction.java | 2 +- spirit-starter/pom.xml | 2 +- spirit-starter/spirit-starter-java/pom.xml | 2 +- .../com/sum/spirit/starter/JavaRunner.java | 4 +- spirit-starter/spirit-starter-kit/pom.xml | 2 +- .../starter/kit/core/CustomClassLoader.java | 6 +- spirit-test/pom.xml | 2 +- .../test/java/com/sum/test/block/Block.java | 2 +- .../test/java/com/sum/test/syntax/Syntax.java | 2 +- .../src/test/java/com/sum/test/type/Type.java | 2 +- spirit/lib/spirit-common-1.9.98.jar | Bin 38253 -> 0 bytes spirit/lib/spirit-common-2.0.48.jar | Bin 0 -> 40626 bytes spirit/lib/spirit-core-class-1.9.98.jar | Bin 29473 -> 0 bytes spirit/lib/spirit-core-class-2.0.48.jar | Bin 0 -> 29631 bytes spirit/lib/spirit-core-compile-1.9.98.jar | Bin 55686 -> 0 bytes spirit/lib/spirit-core-compile-2.0.48.jar | Bin 0 -> 55927 bytes spirit/lib/spirit-core-element-1.9.98.jar | Bin 49145 -> 0 bytes spirit/lib/spirit-core-element-2.0.48.jar | Bin 0 -> 49689 bytes spirit/lib/spirit-core-lexer-1.9.98.jar | Bin 21917 -> 0 bytes spirit/lib/spirit-core-lexer-2.0.48.jar | Bin 0 -> 22166 bytes spirit/lib/spirit-output-java-1.9.98.jar | Bin 33578 -> 0 bytes spirit/lib/spirit-output-java-2.0.48.jar | Bin 0 -> 33935 bytes spirit/lib/spirit-starter-java-1.9.98.jar | Bin 6412 -> 0 bytes spirit/lib/spirit-starter-java-2.0.48.jar | Bin 0 -> 6480 bytes spirit/lib_web/spirit-starter-kit-1.9.98.jar | Bin 16524 -> 0 bytes spirit/lib_web/spirit-starter-kit-2.0.48.jar | Bin 0 -> 16560 bytes .../Main.sp | 0 spirit/target/.keep | 0 spirit/target/com/sum/spirit/lib/Maps.java | 79 ++++++++++++++++++ 43 files changed, 126 insertions(+), 62 deletions(-) rename spirit-common/src/main/java/com/sum/spirit/common/utils/{FileURLUtils.java => URLFileUtils.java} (98%) rename spirit-common/src/main/java/com/sum/spirit/{common/utils => lib}/Maps.java (67%) delete mode 100644 spirit/lib/spirit-common-1.9.98.jar create mode 100644 spirit/lib/spirit-common-2.0.48.jar delete mode 100644 spirit/lib/spirit-core-class-1.9.98.jar create mode 100644 spirit/lib/spirit-core-class-2.0.48.jar delete mode 100644 spirit/lib/spirit-core-compile-1.9.98.jar create mode 100644 spirit/lib/spirit-core-compile-2.0.48.jar delete mode 100644 spirit/lib/spirit-core-element-1.9.98.jar create mode 100644 spirit/lib/spirit-core-element-2.0.48.jar delete mode 100644 spirit/lib/spirit-core-lexer-1.9.98.jar create mode 100644 spirit/lib/spirit-core-lexer-2.0.48.jar delete mode 100644 spirit/lib/spirit-output-java-1.9.98.jar create mode 100644 spirit/lib/spirit-output-java-2.0.48.jar delete mode 100644 spirit/lib/spirit-starter-java-1.9.98.jar create mode 100644 spirit/lib/spirit-starter-java-2.0.48.jar delete mode 100644 spirit/lib_web/spirit-starter-kit-1.9.98.jar create mode 100644 spirit/lib_web/spirit-starter-kit-2.0.48.jar rename spirit/src/{com.sum.test => com.sum.spirit.example}/Main.sp (100%) delete mode 100644 spirit/target/.keep create mode 100644 spirit/target/com/sum/spirit/lib/Maps.java diff --git a/pom.xml b/pom.xml index 11e0626f..189b5ed1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.sum.spirit spirit-parent - 1.9.98 + 2.0.48 pom @@ -43,4 +43,15 @@ 2.8.0 + + + + maven-surefire-plugin + + true + + + + + \ No newline at end of file diff --git a/spirit-common/pom.xml b/spirit-common/pom.xml index c13145b0..bee67c6a 100644 --- a/spirit-common/pom.xml +++ b/spirit-common/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-parent - 1.9.98 + 2.0.48 spirit-common diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java index f93565fc..3fffd494 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java @@ -13,7 +13,7 @@ public class Lists { if (items == null || items.length == 0) { return new ArrayList(); } - List list = new ArrayList(); + List list = new ArrayList(items.length); for (T item : items) { if (item != null) { list.add(item); diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/FileURLUtils.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/URLFileUtils.java similarity index 98% rename from spirit-common/src/main/java/com/sum/spirit/common/utils/FileURLUtils.java rename to spirit-common/src/main/java/com/sum/spirit/common/utils/URLFileUtils.java index 910e1d7e..a98963ba 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/FileURLUtils.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/URLFileUtils.java @@ -12,7 +12,7 @@ import java.net.URL; import com.google.common.base.Charsets; import com.google.common.io.Files; -public class FileURLUtils { +public class URLFileUtils { public static URL toURL(File file) { try { diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/Maps.java b/spirit-common/src/main/java/com/sum/spirit/lib/Maps.java similarity index 67% rename from spirit-common/src/main/java/com/sum/spirit/common/utils/Maps.java rename to spirit-common/src/main/java/com/sum/spirit/lib/Maps.java index 4c7bb4e7..0681d8bf 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/Maps.java +++ b/spirit-common/src/main/java/com/sum/spirit/lib/Maps.java @@ -1,4 +1,4 @@ -package com.sum.spirit.common.utils; +package com.sum.spirit.lib; import java.util.HashMap; import java.util.Map; @@ -76,35 +76,4 @@ public class Maps { return map; } - public static Builder builder() { - return new Builder<>(); - } - - public static final class Builder { - - private Map map; - private boolean underConstruction; - - private Builder() { - map = newHashMap(); - underConstruction = true; - } - - public Builder put(K k, V v) { - if (!underConstruction) { - throw new IllegalStateException("Underlying map has already been built"); - } - map.put(k, v); - return this; - } - - public Map build() { - if (!underConstruction) { - throw new IllegalStateException("Underlying map has already been built"); - } - underConstruction = false; - return map; - } - } - } diff --git a/spirit-core/pom.xml b/spirit-core/pom.xml index 2e44ac6d..eab6d87b 100644 --- a/spirit-core/pom.xml +++ b/spirit-core/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-parent - 1.9.98 + 2.0.48 spirit-core pom diff --git a/spirit-core/spirit-core-class/pom.xml b/spirit-core/spirit-core-class/pom.xml index 69181496..4b34723f 100644 --- a/spirit-core/spirit-core-class/pom.xml +++ b/spirit-core/spirit-core-class/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-core - 1.9.98 + 2.0.48 spirit-core-class diff --git a/spirit-core/spirit-core-compile/pom.xml b/spirit-core/spirit-core-compile/pom.xml index 797c2b8b..3fcc3b5b 100644 --- a/spirit-core/spirit-core-compile/pom.xml +++ b/spirit-core/spirit-core-compile/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-core - 1.9.98 + 2.0.48 spirit-core-compile diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AbstractURLClassLoader.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AbstractURLClassLoader.java index c5d1d687..8f210d3a 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AbstractURLClassLoader.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AbstractURLClassLoader.java @@ -14,7 +14,7 @@ import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.InitializingBean; import com.sum.spirit.common.utils.ConfigUtils; -import com.sum.spirit.common.utils.FileURLUtils; +import com.sum.spirit.common.utils.URLFileUtils; import com.sum.spirit.common.utils.Lists; import com.sum.spirit.core.clazz.entity.IClass; @@ -32,15 +32,20 @@ public abstract class AbstractURLClassLoader extends AbstractClassLoader String inputPath = ConfigUtils.getInputPath(); String extension = ConfigUtils.getFileExtension(); Collection files = FileUtils.listFiles(new File(inputPath), new String[] { extension }, true); - files.forEach(file -> this.urls.add(FileURLUtils.toURL(file))); + files.forEach(file -> this.urls.add(URLFileUtils.toURL(file))); // 添加到映射 File directory = new File(inputPath); if (!directory.isDirectory()) { throw new RuntimeException("The input path must be a directory!"); } - URL inputUrl = FileURLUtils.toURL(directory); + URL inputUrl = URLFileUtils.toURL(directory); urls.forEach(url -> { - String name = url.toString().replace(inputUrl.toString(), "").replaceAll("/", ".").replace("." + extension, ""); + // 去掉前缀 + String name = url.toString().replace(inputUrl.toString(), "").replaceAll("/", "."); + // 去掉后缀 + if (name.endsWith("." + extension)) { + name = name.substring(0, name.lastIndexOf('.')); + } nameUrlMapping.put(name, url); classes.put(name, null); }); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java index 5e1a0f19..3e2b7495 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java @@ -9,7 +9,7 @@ import org.springframework.context.annotation.DependsOn; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import com.sum.spirit.common.utils.FileURLUtils; +import com.sum.spirit.common.utils.URLFileUtils; import com.sum.spirit.core.api.Compiler; import com.sum.spirit.core.clazz.entity.IClass; @@ -39,7 +39,7 @@ public class AppClassLoader extends AbstractURLClassLoader { @Override public IClass defineClass(String name, URL resource) { - Map classes = compiler.compile(name, FileURLUtils.asStream(resource)); + Map classes = compiler.compile(name, URLFileUtils.asStream(resource)); this.classes.putAll(classes); return classes.get(name); } diff --git a/spirit-core/spirit-core-element/pom.xml b/spirit-core/spirit-core-element/pom.xml index 439abf09..c92c5c44 100644 --- a/spirit-core/spirit-core-element/pom.xml +++ b/spirit-core/spirit-core-element/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-core - 1.9.98 + 2.0.48 spirit-core-element diff --git a/spirit-core/spirit-core-lexer/pom.xml b/spirit-core/spirit-core-lexer/pom.xml index 7907d8f5..5b9fe6d1 100644 --- a/spirit-core/spirit-core-lexer/pom.xml +++ b/spirit-core/spirit-core-lexer/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-core - 1.9.98 + 2.0.48 spirit-core-lexer diff --git a/spirit-output/pom.xml b/spirit-output/pom.xml index 424bebb2..5758ed82 100644 --- a/spirit-output/pom.xml +++ b/spirit-output/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-parent - 1.9.98 + 2.0.48 spirit-output pom diff --git a/spirit-output/spirit-output-java/pom.xml b/spirit-output/spirit-output-java/pom.xml index 8dfd062d..7765d24f 100644 --- a/spirit-output/spirit-output-java/pom.xml +++ b/spirit-output/spirit-output-java/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-output - 1.9.98 + 2.0.48 spirit-output-java diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java index 84a07c24..256b63b2 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java @@ -6,7 +6,6 @@ import org.springframework.stereotype.Component; import com.google.common.collect.Lists; import com.sum.spirit.common.enums.TokenTypeEnum; -import com.sum.spirit.common.utils.Maps; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.compile.action.AbstractElementAction; import com.sum.spirit.core.compile.deduce.ImportManager; @@ -14,6 +13,7 @@ import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; import com.sum.spirit.core.element.utils.StmtVisiter; +import com.sum.spirit.lib.Maps; @Component @Order(-100) diff --git a/spirit-starter/pom.xml b/spirit-starter/pom.xml index 00f7f2a7..f757ef9f 100644 --- a/spirit-starter/pom.xml +++ b/spirit-starter/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-parent - 1.9.98 + 2.0.48 spirit-starter pom diff --git a/spirit-starter/spirit-starter-java/pom.xml b/spirit-starter/spirit-starter-java/pom.xml index 9808a4f1..d2b7209c 100644 --- a/spirit-starter/spirit-starter-java/pom.xml +++ b/spirit-starter/spirit-starter-java/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-starter - 1.9.98 + 2.0.48 spirit-starter-java diff --git a/spirit-starter/spirit-starter-java/src/main/java/com/sum/spirit/starter/JavaRunner.java b/spirit-starter/spirit-starter-java/src/main/java/com/sum/spirit/starter/JavaRunner.java index 33b1f560..666a3276 100644 --- a/spirit-starter/spirit-starter-java/src/main/java/com/sum/spirit/starter/JavaRunner.java +++ b/spirit-starter/spirit-starter-java/src/main/java/com/sum/spirit/starter/JavaRunner.java @@ -10,7 +10,7 @@ import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Component; import com.sum.spirit.common.utils.ConfigUtils; -import com.sum.spirit.common.utils.FileURLUtils; +import com.sum.spirit.common.utils.URLFileUtils; import com.sum.spirit.core.api.CodeBuilder; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.Import; @@ -49,7 +49,7 @@ public class JavaRunner implements ApplicationRunner { System.out.println(code); } if (StringUtils.isNotEmpty(outputPath)) {// 生成文件 - FileURLUtils.generateFile(outputPath, clazz.getClassName().replaceAll("\\.", "/") + ".java", code); + URLFileUtils.generateFile(outputPath, clazz.getClassName().replaceAll("\\.", "/") + ".java", code); } }); } diff --git a/spirit-starter/spirit-starter-kit/pom.xml b/spirit-starter/spirit-starter-kit/pom.xml index e3c6b632..b338a663 100644 --- a/spirit-starter/spirit-starter-kit/pom.xml +++ b/spirit-starter/spirit-starter-kit/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-starter - 1.9.98 + 2.0.48 spirit-starter-kit diff --git a/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/CustomClassLoader.java b/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/CustomClassLoader.java index 7d8235df..afcd25f2 100644 --- a/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/CustomClassLoader.java +++ b/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/CustomClassLoader.java @@ -10,7 +10,7 @@ import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; -import com.sum.spirit.common.utils.FileURLUtils; +import com.sum.spirit.common.utils.URLFileUtils; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.compile.AppClassLoader; @@ -35,7 +35,7 @@ public class CustomClassLoader extends AppClassLoader { classNames.forEach(className -> { if (contains(className) && findLoadedClass(className) == null) { // 注意:这里间接要求,部分编译时,依赖项目不能是内部类 - Map classes0 = compiler.compile(className, FileURLUtils.asStream(findResource(className))); + Map classes0 = compiler.compile(className, URLFileUtils.asStream(findResource(className))); this.classes.putAll(classes0); resolveClasses(classes0); } @@ -44,7 +44,7 @@ public class CustomClassLoader extends AppClassLoader { } public String getName(String filePath) { - URL fileUrl = FileURLUtils.toURL(new File(filePath)); + URL fileUrl = URLFileUtils.toURL(new File(filePath)); for (Map.Entry entry : nameUrlMapping.entrySet()) { if (fileUrl.sameFile(entry.getValue())) { return entry.getKey(); diff --git a/spirit-test/pom.xml b/spirit-test/pom.xml index 2e7e86c7..d89c27ee 100644 --- a/spirit-test/pom.xml +++ b/spirit-test/pom.xml @@ -5,7 +5,7 @@ com.sum.spirit spirit-parent - 1.9.98 + 2.0.48 spirit-test diff --git a/spirit-test/src/test/java/com/sum/test/block/Block.java b/spirit-test/src/test/java/com/sum/test/block/Block.java index 1d9e4b38..5459b106 100644 --- a/spirit-test/src/test/java/com/sum/test/block/Block.java +++ b/spirit-test/src/test/java/com/sum/test/block/Block.java @@ -3,7 +3,7 @@ package com.sum.test.block; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.sum.spirit.common.utils.Maps; +import com.sum.spirit.lib.Maps; import java.util.Map; import java.util.Map.Entry; import com.google.common.collect.Lists; diff --git a/spirit-test/src/test/java/com/sum/test/syntax/Syntax.java b/spirit-test/src/test/java/com/sum/test/syntax/Syntax.java index 68ce7baa..73090331 100644 --- a/spirit-test/src/test/java/com/sum/test/syntax/Syntax.java +++ b/spirit-test/src/test/java/com/sum/test/syntax/Syntax.java @@ -4,7 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Lists; import java.util.List; -import com.sum.spirit.common.utils.Maps; +import com.sum.spirit.lib.Maps; import java.util.Map; public class Syntax { diff --git a/spirit-test/src/test/java/com/sum/test/type/Type.java b/spirit-test/src/test/java/com/sum/test/type/Type.java index bbcc0070..02570515 100644 --- a/spirit-test/src/test/java/com/sum/test/type/Type.java +++ b/spirit-test/src/test/java/com/sum/test/type/Type.java @@ -10,7 +10,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Lists; import java.util.List; -import com.sum.spirit.common.utils.Maps; +import com.sum.spirit.lib.Maps; import java.util.Map; @Deprecated diff --git a/spirit/lib/spirit-common-1.9.98.jar b/spirit/lib/spirit-common-1.9.98.jar deleted file mode 100644 index 58378ea71524724e655ed2281c98a5fce5c4eb9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38253 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%0AnXaTkYy(Syx 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 diff --git a/spirit/lib/spirit-common-2.0.48.jar b/spirit/lib/spirit-common-2.0.48.jar new file mode 100644 index 0000000000000000000000000000000000000000..096fb90c847740dd3e894bba10744f8fec31dd39 GIT binary patch literal 40626 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 IQRoNp0QTK(;s5{u literal 0 HcmV?d00001 diff --git a/spirit/lib/spirit-core-class-1.9.98.jar b/spirit/lib/spirit-core-class-1.9.98.jar deleted file mode 100644 index b8b35960e34ef70860721a3b26a5c2a8a1cf7be1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29473 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 diff --git a/spirit/lib/spirit-core-class-2.0.48.jar b/spirit/lib/spirit-core-class-2.0.48.jar new file mode 100644 index 0000000000000000000000000000000000000000..21b195775651bd3f5cab4187dd6e8ff33147c58a GIT binary patch literal 29631 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

AD*YvyKWjS-6a&;b3CWLk7trG(PF zRlVf`G2(ok)$tUm+nC|SVq@!JDX+1a)1o6bx6g4gY*PSHu{ z#1&iOx45)YRbqS5(ZNTwbe_;m55plfTsWkJ1mT2aMsX4HET35A7PW^fUHy?gnvZ7| zfwZPi=bcs!rFZE%=W7t-*pRbV=X>02qIm*KC@L>XxA_H>l>{hGa#{NY$y9n;Avf zV53Yx{UQ_KZ-ZrvZGl2#U{+Popdv%j9RG}3ct@zmXWR8*{G^Q^`oIn`zImBSgiZ7o zP58BbB9eSx^zeXfb&bXN?c! z($?kZzjIR@^yW+xDrNWAyRUBl^bO1Cz7d%nx5C8ENa5SoxlDY5S_@FYr`rJ>qYBqM zI7a<%f9%why1sbFvflsw9n123e=zP0lY+`#IV-@R(w5EWYpDF&Il1c^9Ha6Njp{d; zraLu-8|2pIQbhCx{Nb5_%;H2wR^o}xtR`$eJtO@Fq54~P+y_YA(;2F*iiahI@1>(xK3}kFxUqs2blQg1DesqjH%MoJ=b67%UAt{GO7a`yCD3nO>~%65y$< zSQD8pbS0-6U$4q>aOno{bpGEb(MXXI(Iez2N{yrr1$~ zqsvnaKjj?rcr)@`P^Bze2nKHO4j9rTea0mjUa)Pt&SxasJf4jlS`to7ekXK$@ksdW z#*YKnmX$$kGE~S-bnEXP->&X8>X&)n{*ZHPoa*C_;a%uC83a1w5+UKitK>4*b+#vJ zQ^W=ZIraF&Qr#Wl#OyJ?!y!vpOQmvf!c$p+)E9j$HUu%LTOd9VRLWs4#JjjbE1b@9eT`Ww zGA-$vZp6Cn6^!s%HdsgxsG5}3d{?(!Y0=sGF9z!x636j(RF4o*FIRc#j8_~d}v6CLU1e^ z3}Rds--z2~Bg!B$XTeu*nOO2q6P=XzW^Cct=5vY8P~M4(OwS~gDz6kOuAT6Qqc@LG zZ*r^QABPvj5>)U+D3XomlBWlWY^D-L4W@lM7MMhL~$Vk$t59s&EMT zLw{t%^P~?lo=8e)n;#z^I;ilha3wF=KWwM56(h6Pp?Gd^GZ~vJy9t#hpFx9$Ie^X*^~x6kz5M z&RkXaz%*IDEOA38fCT?e_Cjj5uSu>KZ}6RmL33K(z8;U37#U0p*l783_@8$?LtDu) z>8TD{MOs$}M}dXvxg3W{3q!@8plOg-GnRN=|Ac|k0je8VEJJXNr?X{#5CUO>FL=FI zpdXiR7(Ogv(4}OlIAlu~CsaD=G|)4+Lr#-qYRZUNDRSn81X6rwIIyT#8{4d9!-NDCnL!tx6W2N=-yZEX1w$ju4Z(zoJWtV zg1C%RMn19A5{rtqJ9aHf8tAHS;-XOTyoQIvEhISgNij*q>V*A1T3Sw_c>Qt+dt+-y zWNd|k#s`3ObAq{5;#ed7qWXPTidrvynInFteL0s@M!ipHJiy&*0k`ZoUAwP1hkoK2`W<^*@UBb0{;Jm*vNpJ&H?@P_!drYFAe5m>$ z$y*=I;b_rXQH3WJkiG0QU_PVWILAy9w7^qM*kpq|S!QCNzNQ^N|CUhDg(5t2q9}BB z{xDW>lCQlEiFtIvAx@{Dd#l928Oe)`awFuu=E4vb&1xy_v&TD|=q2*VH7~%SXqNrNK@Q1oFXl5Zbqc*EESxI!#c|s>0m%sIzSR zq+~6gMdd~mi_|Km@*C3BgC3!vA--V|*>bWVG_Rx^_aHK`0fYxG$br%1(A?vBK8~pq%Bu^-p}X$`iCfEL|Mn-k35kgUXM;^%Zt4yKefIkqayhz>UpGRcwqdsWpRFR zN0(?;XZCnW;(|V$ao+X}KDzmI=t_XJHJU*pLXCukTaoX zW`-MKCN7S|gq3v<$!ix?dNg}Y=LK%^@;Yh<67_4LZApjj5b^lOV=8qT$G!CI`H4*P z{w`<}dx%RWI1GacJrD_@ru&>~ymy?E-(m%z)Fq9q(!D}>5b5BREz%%$pT_rHju}2q z22;_v-Yw@=yehwqSnt7x9k(41^cz6s+#4Y;UfC&0ZIV~;j2+QBsouZSzg7KN4ozRP z`9-yT$Ov=#vk6JMQ*@4zMf$?Z_PAnKV!opKcCbxohsN%0@1U68DWu-_JE+cga~gj6Z+{y981osSu74YFA-As+e>XIo?>Rk^$u zn^7+)DALpOb=RjS6z8>=6E^6=2`bPH>V-)T<+(j7{N5Jf7pBdA0YcR9R5ZH%b?7bM zBU%YPB*?OBE4~pvhfUem5aNb;W320QwqHLm7lHZuZWK;=J_L z#A!vcC**?rl!OGyL?2ZyEB`Ad`Lnw5mX)}wE_EUeF+*!zH zcpK%ZkQGnBiNf0*tn}mK5r-;m)e_WQsZh5G{7bj7{_&^;^;@e5hNo6Vh2w`8LhiY! z;V8&jNWt+6v298-divWum@Fh!( zW=Pv6lReB7l%iLxj$e2^&&~X}=^Eh#sZz3b?&g5nW1Qf)C!^h;++IUSH6D}S8)~;@ zXjA9A5J<&{in%AzdD}^AW89URC{CRVYgVQgAFz63R*R;0VJyv5C`tJvaIB?a3Xs!Y zR%;^c$d80chl!eVF(~=uT!s4Ht;#{dXHo((SxT=64K#K(^Sj?h358Ovt~nprB^syw z=)AwlQ0hz{Wioto09*)?VUR&t0%Nz(vw3V} zL|GAE(H(4>WP_xVq-SMiY)y3;3tyjz*T1}3pK;S$CJuD`QoZqHEyPP=cW-lqdZM8A z+ygX1+B^#3ZU}$IWc@4 zoyIZJ+3owH6qdZTh3{CD1@Zu9U7;q~F@XWn`>_I$)hP)YOD zk(B953dUIX&!@*rtVxFgIBG?5$K=eDMEkgnr#AKkXu=9aG7kC498r;|mvY`sbPDsX zXB+XVb&-6Uv=h3{>8wKys8O}7d4C;vlfYaJY|ou};$&yw7%$+iaSV^766l7^(A^u} zz(>K6F-8Bt5YL$n6sCkWt>H8dYRMBNsG`-RC|QF+`Cej;^Ze#>81femeZWoh#bH9*grcx&TM2Dqu3n3ZE z*v8J+Lrl+YbY1Apu#r(#4x@F}DmUI#sqg6vF2#)^q&=jea7AQ6)csdaP1UE-@+7VL ziOQrxaf+_Vj35A_49VqK%P{NIH=FcSlbEvKSkEH?vtDLSWQk3p#-=7BsME1HBUR2M znxW=?a)q-D*;RRm0hUO^y(NUe1uj5-(4QcC;HrAOW@zaz;*K@AVXwzNXZBjnbFw<{ zF!@3p>7q{4x|Rg%VvD+|o&a6n7k;{UF6iATVKZe#?5c${8XA*4Z`P3@S=%aW$g9G% zxwdzJqb;85LWIeT82Ky+AXA@^Le+i9hOjK_25+T7Hrm`7z#%~sPN^yLi*?|!HQiVX zy(&REJ;B6R@N!tiLN%kqhd1F_>M4GreQ}YT9T_V{DH{0h^-rj`=|br`OKh2m)D4;q zx!Ct*M`Q4!-pV$100sR5mum~8Fzt~t!$Lc?waC39dhkd!*ywzf6)h&7C>G6?zsp;& zZKzYeCGMiyrsnb-6Gxjmhm?PJn+G$ZlPr6upy2BO-u!O64odzGLXTt)r-w?Lyo;8e zWqXHX%n|l0!P^e5yaIVU!6K6NY(Zl?0X}2Mca1T#m>5#$M|F&h;**F*-?)8#+9ogf z$rHzBsD&MwJK^Cc(iwpz{_R{B{B64ksfi9ZLFc>9gj(!!yQ=;-2^D}Fk~(E4DpN|eEE-fuB$ z#NG=DjqmHW(Ep%YEds>nM5$tj_l)#<@?@6=I}Ke&wh?*OdkqBiY>7ZeIxcV!@Xei9 z>m%H0@Y}X<^~_W+w5)rmNFEPfhnv#gGgWk;b3;z|EnUNSpfQJ1AmD-*){*hvtTr_M zzW$hGc{`!W;Cgt)Y0LRI9_8{W4dXK&zpotCGl7|=9vS!U`xYYL7k#}Orr*?Wz8S1% zzbpTA>LIKAgtk=4J%qwV8*ewx-5RWXm$HXpn0g8}1tMkeT2)mirL>sxDHu`u9pJLW<9y45sWcuWq<=L9^ zKYaN~FCm+|U!$uMhXPP4A1W|H7}0KGo2Fzx#NZkX4FEZ``l8?3FVXP!9Z*D-cM20l zrhDi>gm(ugewdkPC+JIvn^&_Dq(hT@;9)^xjY*|7#dFj<=Aclv$08~EXyH|Cqm*nm z8G3DOa*dB4J0@*(FLtm+@O3OJSL-`3@>0x*2zRC5WFm?pI^i=4=`nbO890321l`ju zQ@+R1L?7?*W$E4K^=Mr#X<4*Y&3;}D?0l1ce>l?<0TAtS$L+1L`qv4m;fy55=gkHqGtD`txg*9qu67ua8*2?>XBq?c*zSQy^5>DfL!PHYeK+|?q< zgn(&uwj@TnGHq$VMIjX+e0L{~Jl#+$7HWcHXi&xNH`c>FwaYS#ME5~{VFazN33W~o z6}wS@n^r>ANv{#3RC^KIA_HE5+N}qy5}!Lq=pOBJL9&Vmx1*10PR|hZKNBx#B;x4h z7OZ?wn9J{8|6a**^6;5zr{|YSr4K=^@RZBaCm3>Lq2!$Af6pfU-gZp0_@IGH@96?E%4X!N z7IbSC-Y$3nTK>SpsP`kH01SZ-W=2DYK0=n7gaIzdveA7HCddN-uHKxAIJ1P2TZvuo zX~S3KXX`ljvvchwt&C51Lru0kiUDlw3O9ieMxEZb9=Snmz_9Xz4tvV|q-YyS>ejd; zy4LLUM*1)yZ7Yw^e9rP}5sN7~Dr&p05y+JyeF7;x3k3 zdO}=1;5I?)oVH!hLv=5@;w39b=r){X9hFi9;hSb;=FdGLl1uRoI4DoX9INZXdO<4F zkz;))e4%mye)ccuFzx!E4NJNd@_iA@=fEiQo!psXS zmF~hIlnKyMep1c6HoD&6n#)i`<#cKrTGFic*;g97Os}2|BA$8@WO+SSVW-nlItIk5 zH={DFsL(aE??V#0Ok$~-&*F5<6i#6XV>y4`}?621KV?@jHh+0SdnT>kUrmgP+Y{rTT!-&K&g zBK);x3v?mtkL}WM2lV$#wf^r~TvmDcwq3UP1pW0-egE%TT~-_Uwq3Tm3B6bS+3LUb zL$167TYBcQ3d~hw!M`^CqbAI+371u2t_aq@AbhJ4^J~gwm6$6^)-NdELK}YPjC+4# z{&Tjcf6MtJMB;ZivLA4S&@lkUxBqd^x83@-!2Qo@TEC@zn~nG#?Z@+;0Hyu6hyGb} z=GXqdtUB{;yX-Wre{Bps&L3;g{F-&Cr@CUnL6rb7I|9S{>tn;!Vg9@-&7b@%Z$&8m zXQ$v7HELkNuti<2z-G|P^=II3=T`jt@;6r{USRRCX~nPbl2B>zukn8d>s&>6e47V= z<-_LJzT&4qd&A%J|8p2WN5kfyyh4vbukgP|f0vCCcCTSm`dy)C3I7TD`viZmY}lMk zS8O-(f5QGQLlZ0-HfPKgnv43MpkXq|z~W&ub6nw>>HZ1+7kN5h&A>*ZUztgV>UIA9 zyk465d5?jOMY|$@<^Ct+A0yLX_Zv1i>WbdY`#bu#yYSV8bR{-|wE!Czab;j;e#{)2!FmJO>Qx?)es|Bih%_y0rE8(2K7Xy6Jjt^CjM-$@8y;jk+eS8x{1 ze+K{gx&^Eq*s1+1J0@EH&dwhb{ji2$r@^lbWorMg4E^=~^Ru~%E4;43|Nar=$C-=o z59MdG09Uqb4F8=i=$yd!Mt=6@du3$K=>Lk5pS|r}8BqcKJ0n-~J<9UP&{YpOI9lje NAT;3=xyj{U{{w#5;wJzA literal 0 HcmV?d00001 diff --git a/spirit/lib/spirit-core-compile-1.9.98.jar b/spirit/lib/spirit-core-compile-1.9.98.jar deleted file mode 100644 index f83cd49de709fbc17a944db29cb730aa4295b038..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55686 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 O@fr^B9yajpxBm}$RgfhB literal 0 HcmV?d00001 diff --git a/spirit/lib/spirit-core-element-1.9.98.jar b/spirit/lib/spirit-core-element-1.9.98.jar deleted file mode 100644 index 23e56d60a73e67a4ebe8d09a971beffa9a964123..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49145 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 h()bnsuQa#*A2~^AkTHI{{iD}BHsW2 diff --git a/spirit/lib/spirit-core-element-2.0.48.jar b/spirit/lib/spirit-core-element-2.0.48.jar new file mode 100644 index 0000000000000000000000000000000000000000..f45307d13eeb854683964d2e34315045e59dd50b GIT binary patch literal 49689 zcmb5V1C;Ddk~iG8ZQHhQ+qP}nwr$(CZQHipw{Q1-?|d_}@6PVK&+J#{WYzziiiiyS zvLZ4vOI`{X1Pb79FI=4n#sBZ&A8(L}>wSg8xnd@ec|om%pNd z|4&p-_7;v7&VM2DZ%+B!q<<6n4`L%bN0Yzc!1y0H4D2obf(z$=;4-l`u`#jzD-DVN z4X1&TvxS}QUrhb)1pJxa!r9|51Q7ij4NM&kZ2rn)|Bm0q*}~fCFXsPSK>q{ZHU_RH ze`PJ+e<%JEU%Ef>rTe#FVEVVbe-}afH;B;w*U&)#WNJky3hd^KSN@T6^Jmcf8UHVE z{S7L@c1A9Li@c(Vfw74rosqSHlar0CAk?4$OtyK;rNljaA-dDUY88Z#p!|JrZGp8# zm&p#4?@SQ$Khh9}Lo^_vW1(#D5Y5brh(keT^xJL*mDFxz zLwCjHD7b=h#%fY3 z5i5c8@6U3}p}w`?2lm6)^r%-Kpn{-Q3L~znGlEZ&`C%PGcaZrJn=2cUIcmMQfl<>aq4l`fYRvu$4Uc~q z5;8Kvz#vRF=IPrmL)_U7oPKOTRBjYsfzP;#Hwg{7E(yKjFcWNuU9;rS$TD=JaP|`r zc}WVQV5x@vG-R15iu@_ns!AupHQDcJFRGK$>Dtqu(_ea6y$Pk8HWbTGP1@ky3XI62 zE$KJR(@1x-gmEEIt{s(aX z?u(ZT&o-k!ei#J$YhNgt*ckj-ct-LDj!yrKe@xtz><|Nj$QbC)sR&0+v`u=BbE}F`Bu5~IB6W$xJhRT`BC(pvllvqUB9SS;U={mFhbXPO9`MH- zM+(M8f8nC%`l9VSRmxuto~cqG31;hAKMmUNz9mVAxQlr7og68z2Mrd;W371f(gZd2 z-J(-I`%`{BAFOEa*TfWb({_tmI?QP*3(WU7!-Xz6Gys+0q&ui|3Y>)H=FEICX$ zY&ncIT&z28yKFmc&siYDM-C6c|1xdzH6?9{= z>~@&%J_RZo?Am!fVq2otqOHt!W9ATP={RHo$AKJFd0a_L3%++64ecQKr}&Yo?f!PR<2hEMpmC}keDO0l?f1P9{|~Vh zOVl9Uu}4sSjV3fTbjc&HIbxmmLCDutaSljuB4m(85*h?jqf6RJ9B@`24e1vQnyV0; zN>McPOPWz68I$qkDOga9Hsecadn}|beD>aamOcx8>|DDwryQ^4{qlaZKe?Xv`0aLQ zczE89B+UWzqqXh;qYu>ZS??VHgW28p>)5x!PnKWh+hXh<2Y4A20%^T@?EAVmf#dnN z$-mX$xnp=nK@!TN<7Sl4-Ag%VKLb%1UAUW(m&5^C3Vz-{|pi`{z` zde?OTKKv1e^h-PtU+Nwi%+Zcv!3Tj5@iK}@9j`-(vl`?vG!^Q28SzCtUyTulHO<0o zA6m4iL6`wCRsJhDDCw%cRGjZ5Wd!{N=XzI0!V`t`2ze;quD3O==Onym=Oe=&K%Z|Anohk!GA5|9i z=)mqqo~2nM4t|#DraDXO&~;hzv^at7ar3nJr|TionkZ9b!rVb}fgv5~8OqZYhY8KS z9`h)$cgMCtOUt{x=vpYJ3D~U#ZP1NOQx6;cHux=~NYtxcDyFjRX9KsJ1()dyMNmnJ z_MMSDDtq#A0iKEUuCLXquQ)I%7L9CUhHm;H|{Eqtf zV0xgpq43aBadG>MyRSGeQ>v0n&Q`{*ax~meDYA~;DCqnNZ^Y6LTxe)@t{Bb=(?<(l zeHl0dwd)81!zQh$O(4=OaHztGvC?W`ld?i=Q#&6CSyHxQlnmYpg^Nl$Zi3z`JA z7@MrKG9>IyAsMVE%*|j0s_)(PRaHeVwp(>ECem6=Ii9RJ(iOTGS4WWxDFfn#gaZ?M z%G>)|>(zWgBi>5JOx#uUuKhCIcg)BT?S64nPH_fK)-KB4-QE`va^E!7`n*xWQhmB4ta=i`U2M^H!y|W^M-dYzouWo!YhpEEAUE^cC z!sGO}f?wEL?+$bb@jo-H|4hsyoNhWK_7^Kj<}{Ipp3c59z}Cn=Z$&99_rOQPgMs&# z8h|#Oj>o`5tPo>NEIL+#Gh?!>WiC1Ij7-z8TGD<)>7nED(|s0Y?CLqEkn_r}A%e;x z2{qHZ91JmYI)V|+`i>*_BBTi+H|{Xq9cWLPu%-&p4x;S-88=-CC`(LLCTOE-A{ekK zWDghAB>SQtJ{FJ*{f%`qd-^fdY#n=vK%AGm`!w?^bA_Yg=b(18m`3+R zHw%R6=*-x%brvb`D%=7ODJ<1Pfp~>vC^cohI>nzFHa60jnb^BddbAXdJqLbJ5zG#k z#>-Jtleu}wk|9lL^k{RX^1?*qfjj}=bnO&$4K4kAptpBlmu7MZ66|}aN^;t>B3!dZ zhC3)_>=yx5)$s0a{QYJ0ZG<4-2U{uH3;ItZnrdJM>pR%> zF4P$Z$(8Jx#9L-!hP4sNbo4hx7mv$MS!RAW%8C^nr!=?ypfIbn=DaYfd7jx$u;0Ob z5E$ApcG2`e1u0rWWn3S#{6m2^K_~u;a&~s0u%D7Z9K5o64uEB ze8T8zbfI72jhp~r`v8()LG}n@3&+0p`q2GX{1S~PB(Db`9OMdT^&1xZu9hbHu1%_9TiM^8@^lB1%SGtY#)%YUvn<4ZSBX=Bdi^dA-n$~nAQz0N& z+5<%%<;jF*kUs)EU`hyRVQxkkSt@t^fVPq4nL$y%kM=p?Qr-fOy+N{LjYJ&Q4V!fA zHfqsZnZ3oPE?pC|s!vSA?3Fk{8|(e5!=F^Mb|j~4OGZ4VnOadvW2nStRYpu(x2BV| zOeblX)ih0s2BlFmHJ-0=s&1Mysv4(NX0&Zc^=xX3Pez@qrZ(jf~l_duG9%5(i`DJ;qIQAZXb)#D0Xfo2(=s^CT%A=Lv5ZGm_w zQs-uyM4UGts47OLhT~$PoQ2SG;%Q~+?62+b1#sz7>|dNnw)c4;-BL`hnGC88pj07@ zkoR)}Q=V{Aif4WVofH_5y?7@5M4Z~94r#Mds-JvZWdg0LnXROZE{hQx%I5Lj7sd%8 zJ$GXDd^y5Z+;5&aY_=gQqa`bIXxFswl(}}szFo(1I$AAkqvUWx%8Ds9)e&sUWuMD5 z4$*RE-R1XJ8zkbH;NzizO<#>km-gLm0if#>sG2EUF)bn${2&rb84B95qS2*?(4{gV zc-s)Zt@3Ef$Ykx_5Sl6Jz9=)LwX@AH&0^Q8=!j-#S8R%92TmgTQMPaWsaYr=<4)_? z35R?Nrah-{>`Podh-C_^Dk;+*fxVBm4%0U1ac|k3tP9+=-}3&x8&LNA^6tMI(cy#M zE9hpFxNW4>Wm%)sQqzM(Ma6pvud=3jwMV@hkeP}$9ngAIACa`f!wISd=ma&}Hs-*q zOu!f3w)-Q!5Z)-32gvF`VLEJ#!F5cZoCmJ!022FvF3Nr_I@yKp!879Nr5&5>EGPXZ z%a2#?h2N@Y_YUi-zhwDLnrO6AO_myybZ?8^^V1X*sH$y|6YLebx1w$~tU%IC=1ex9 zJj(}BUD?7P%cnKGX=|ERL`}TO7~3mYf?^H9V4oP;Jpf^_Oql`LO`n}D+_--O*+<+3 zBG-RWmfzp(E56+I|%4jI^Q+FxDDX`{a;G;y)XG!R4@Pl7gzuQ zp8tQP`hVN$A)BE1?wV$>;I;}uhX92%HW!fkhYM^<1^^`_64i_o4YJ@)&Kn~o zN`P*ox@|iQ=xE;;*>eCMj0<;DQl9CJZnEU`?n5SRAx1H*Qdxjn^p1F&>d6sFAy9uh=XH>VPE|wG0V6 zH!k}$cgV@)ojh2D)pL~fmg&XC~IOy zWlQpkg(;OAC0*w*CrIi(@no+pKI$aGLTvlW@`FgB%e=%z=5{6{Cb zQD&BtYT?|pFv_G?2ukkYL8#Z}!JeaRNEhyq17^Y~WJF#g?olxZg53t8Nk~ePQ|W#a zBy3a8uE#b8%OK~NWH5J4HI7Og$eFSyME*F%Mrs5{%z|8TjA@VrF*8Ad*e8l9TlDMI z>XhphD919IVGF-X?Ra|UDg~X9!D4FD-9qR~fT)IP7*5tT$`!cw82i1d*kgGZdujiVm zL(30ry9)l-cbD$)cT&Y#F4w|kq43V$;Z9t9gJWELg4BXGr+z8zX<;i|d@1^~N7b<| z?&3pcTzq5bT)o3;T)m_0P_W1%YGZ92We0(=clSL)OU9cbL-1U#5p(zsvIaX}uySyP z2I-xiaaj(%OD{(oOpB`S!Gn7e*QD?(bO_d1kXa(!Bd6 zP}Pfg(@cLHVUQ$Apba)VO<1?@6sX(HGIGCL;+`9#C3i zon3ZS9jfPVXA$Huf@f%K*LN*JMx}%OlrgJI7|-~)Z7`-Qk!DF-P9V%<0jr!B|U%oWZSRdqI_ans~ASsaoGu_MlM) zM=gM=0jt|Cf_r{B4+Okl|Mq+&&!lTe=Hq=ZPjL_X{??u|>UW;Ur30<%;8m^f^x>H< ztEqmhRZp#cfw@k3i+lX5NNiB#LpA-V{Ju4T*hKUx9iw(xZ=6?EnahZaIaI^x6$FKB zrzz426g%SfIqZ(W$amGe)m(A~PpPu(jFBeZl2y0Ibi4Z}yu|iZsKyOeRmsE0FWUUB z5OafgB+GE7Cy&)YRrZWk#rYcB@<>g@=7R(7K)P%jf|iMsCv}jOoSNGoi_JgN=%ijG>SF`IL^ANsfZ7G1!ajXn{Ai`XS=%k~W!JM?SDI z;`o{IEjTPLaq&|U;JF}*=R|RF#blW?dZ+o0l2tt5iGnk0`)$Yx8W7fNnP0uG;FF%F zP&#glBJS(Iq?<@kK%ZenEh&(>#(qL$qf1IqWTr-a&~ z4a#bRgT|zd4LdE*y=rhUl{*!>f-=bAh>Xk?Yedzu$(G!K837?#0La}hieU#V3jz?V zh{GeN>$^i_zuylZ)c#%T)JB+EQ|-~zq}sGcSgpA3q{~wj`<+49aJER1Z_3rvK0>t% z*T|2!yve~UwUH-D9xU+_(2NiriZ_=6!9EETS!N^Mm{phuvh4E-{8>-zDiKV+`N$Vj z@}f*^y%5oh4R)B^MwrsZi)1K3+@#m6-w`Kr8Am8vvNs_-#4K|#M9Q9`AW36}nI3d+ z&peRF#3o5CdfGSm;ckKTAKtU?;;$>xjQfH(R>aqk@A);gvZB=)9am7g#61;9e! zf5*5h5GSv{T$6T@RkME&v*`UU*%iYj?QMS50NQ|iJa;^GB8d%Ig*^Y!seRCpjwYpk zu%KhzPqoT{G+UGzutzZV84$A*r(Su=NBA2rg`T3j5>0O3yUDpD**1h&ed(laG^3=3 zHXpMlN2gzeOjl09IL)de4_12;#|DTW@L!vZfDT&_(SMqZ8R!52-2Xc${cCek!p7eE z?}sTlYLM#ME2!V}%nU>KiTwx=Bn5=r4Dk`8)(8?{Ldn530zo7#4~*UMY5mh2QfRCS zSBsr3Ev`Ygn%GOLY^7X`rJ6UoH9F0%EuW?_H7lDlo9n;3*2_sa=&uD z_KM2z-68rtDi?xm+9yJ?c*h52@Sgu<$2)|3S-`u=ks5b5IyJkb3oqlJx&yo9>z|;X z{`y0KF%YkU1AND$VZ7=AaS$g(LLce=anS8L{kTAUg!{69c__U@fjgx8;n;bO2TOR~ zU~W++d8mhH!;wWyJ!1WgfO+Wlb^f2*;*q0Aw%d79x5#un`vLgmPxqia>0x2_BItOj zDPlbDNWIqsYWFIHelq=QA_MFo-byqc$|QVb(0h(Y4(Po%1D@Vu;d?V9Z}-6re3VOf zUH8f0GOp*o1nclS?+MZTsV8|5?-kX&wCi)mPjfr(As9cU0Q->ct=N5ukL*By&Bp9a zy@R9YIvm77Z3K<_5?3h$AlX}S#1t30^Y`C{Q=Bf^fSJJ9%tw1j`>-Bx=#sybZ7zCm$zpCUwnAz zbGm#%u7UGvIv%r5&0bmAR>htz^bAfK;YB`%Xm4l(CJ zhis*8*1Vh190s$XJ@2Q8MH*xAQhmAA~qFZLtwU#S34PK#H*4bF);pmCUy8DFAr0T45)TNv-{HLaI^3;838 zr<;y!#ta^phpiIbf702@ey%ESV&r+V0<6}{KyU&lm694E7E5Tl26>F~WUHuIghty& z!WWcoTcoYzotiqQ1C1+V-f1R`7-It21D}X?L1Ji(=!T@F(WJt9k{`lU%q#MA>~6v_ zIj6p!R-r#(V=FVm?f#7ESFf{}wGuf)alq$62NsbliT36@@JIBHhtS1_$CGyD^)s0zdvWsji!l0rQj3`fK+^)!F-DF%qJLpvJWN#@=HwjJn_*S2p znAlf@Jof>ut*^HNZcbj2SLh_wRKBM2_%i#-~h8-@8PY&KNBj-E)^474yd|l}=Y`Lrsb*YlrX|YKLNSlIg!XK)~%UGrFI;vIGfXK5nw}qIP4^MInKIMm;7*H zoD!ulSI2bG__^sum8{I7+G>1mvaI!*c_*@ILQdckux48Be}hS?Cfj?7i$eOcmdz-- z#Lbn(#;VsGR94wlktCMyoE==wsDJ(TbgkITlW&@15+MtJ@vu+V;61Vt#4O=h)kB$d zysF?qIT0PmY^rOju5nUxbNDnmyD}YldJ1EU9@{IEG0@O<6d1|O$!t9%V`n0<{?MQs zrNr-u36*Te8MZsutEjz@?a^W1XrrZ9#$Jjq=4v;6Wodh3Zn3$5W^UuzgT`rKl>?GI zmfF1b;(RzdU3+|<5dM-~nX!09;{rWd#fsM|k+>E;#}T)qxdh&-kVX{$M3kO$(!E-` z8d^H5jHA73BnMZV6z1QOG_@J==XfkmWlosa3@4rOYt@Ny)o3y#mDxNPY}T`h)rhZ; zuI<4nm%Wk427>;SChSOyqm%Q|M!ekVw5{F$y7EZ=4Pin^FA|eNAYQ%+a~^&OsS_Ev zVg{1q19(!FsOpUa$3~?$vqOS|lY~-1Uv_4pdEO8TP|{qG(o~-FTw6;sLnMPTnH}awQ~POxst>(m&q*ve<8NP@^8^~s zYX4WpbOFvE%=o%A#^UG?Z6GV^kt*fFz(bpZ8tj(op8R_wQw|7chg{YDHR=%tjyn;o z?buchKrZeeSN9l~4ALY zXlTaC$@{1kS)I^LI5})F5?DfZ<#f#Aca zvi2A!?`mHiaH7VnS83}Z>9qYb%ttM)M@5^FtlEB2w6T_bt!KX)IZeiet9;I8K(mlv z{E8J%*?21MYxs&VN&uD~1Gxp;k~?gn%g zr89CoQ&riZzQd%Mz58<^kUQd~r)2hMoj`2ELc|lb6w&oj+^qr3OI-#1p{W6#y=f=9 zeh0^(hj*Cm38d%^#f@huyl;4xP@_FQfoJeiTE8x(Zt221TlVb8`Enlr*le2bk(1&J z;T73QQ49rqJS}EQk+Y>lN7jPv_ldU*)eC-lw^x}s? zcFclES+u=ik2aWXpFmNXGL};umQ^COWGym3hZ&pW9%EBJn2r%|O)=gW0DoM^6XI<` zWV%mxYBXIw8%^nj-WZXJitN_jKQo&A0vwf>eFw^G z3p$Z)@`ls%6+yC-E^Hb(o7xjt_K-l*5nCdYZClm}(8iJvrlv)Xw4t;>Mk|&MSMO3r zT(DY{)FY9wjl#=o8Z{5^KX(YeS5s-EG=Um& zh9sn%0QnBX1=_C>;&C(D6Hb;JabZA+r>x8(nvoW%A_}rgn&o3tixA8M<`?I;+AAdT zacn5nr0CCKX`gKi zY_(&oia#9^_znhI+GWXV-|D@Bq`eh0u}xmd*j@KcEo>c>?vxg{iFV|su4@*1WQw;$ zHYpcz5AT?5z0uqv)8;zrrA}`XJLaOEK@)l@7Sn_erWU^Zj=6!x#= zEf@i7N)8wdm=oPfnY~M0Qtmv9AXCnuOI-HWCYQ2qS;|0Fax;fkjJ4qL*1V0e^cj#$ zhgXnCHwPXCMJyxSD0MQjq(=_7*hDO&>Gh#8F7^(HFH0AP`XqD*%;hm6Z#^fo3ACA1 zx%^;XqoAm%xKY?Qmw+*cf`hvZMVlP{Y*AJVuA(f5AS+Bzmm?{W;^#hRV87D-PA?=h zXQZvgERDOGDm*Y4inhL6E{q`j!M_GIkriFMn8{l}ppDGK-N<@4mF_u>zPx0*1i159 zmNnGNVAKefX(`usV}xilzP8}kipEOH$J`*2goDep(FNqjWmc^}GL2Srd$1u(;5R%)z4mo`UJ+3$Bh_tUbpw9XO2(!%U-BrjJY zW0eMVS&EOCkwq346Hr|dHb!9LrhbD0(_3XdL*T!GoM>n^jJ$Td9;yy{yc}D`WG(4o zZpe82F^kOxzh&AZV(u-#HLIV63R>k-U#m_!YGc0T)Zs?1w7HsX9bkBcqG5EIE1aTm zV{(2VOoqCm>B5QZM24P?ng}(}p~i3MD!1Q7Rfr+qAd;z6KO1sa;f}PYmLQ-w0OVkq76eo# zN`|IYeF*+u0L`!XV8k=>lS${c+#QQwAwRqBu8jn-H@?yXzH=3a*rWF_3uZA@e|{y!c)28GTXC|Z zROAnmvgj0vHBy<5=nj!b@uLxDsMv3OIswoyxjPU_^Yn!UnN0QLk6^dISjWS6U)6;Xug;2tcy*38Wcul-LU zZgS*^k`cXxuWV7VfO$>O%3M4@D9v5YlZP-NT%GUQ)>!!lWcmKamraJNJ%5=dN8Xte zW(B9k!VTUCv$~9PS+W*oDUum=Z7t%4=vBsXbaBS7i#-GrPt9Cr@5pnDtAwT6heUjR zcPn68K|iznx)$!`$5?W*-MsLP0%h0MoW|O!x{@yD^{ut-3p)+`bI-Ff&DmUTN6iAn z76Aqv3QuIzxk7EX0fDRJk{sIa+Ef>54J)m2e3(~F#wqHoUijlpJEn{;Or@ry$5!yo zEZ`g;LO*Ud6~BHR83t4!QI7omVqi0aLKOuv?x7uQpd9D*mRefr*%nu4O<@?bpDj1t zlS{@n64(`LqZxdNk&6{#&6*iV5)OIdvOy{7qq0lB&>Y7x0$f)Y+eK-c8lvjXCNf9F zDUpx<`w`O(BlvJ_IYijwklQ)G9GJ9RXvvx_ZJZEI}*HpPi z58zss->>s^W9R&OO=S!A!d;2Ihd{Si&(Z{>-!id=AF{@YrNRmL`1R>SVc7uUq8@R= zfe5P}Mcna_vU;kvfjw=jTTJJy1!yA#&&CwLF+EaoZZcY#UbbYOG z_=u+3Ie#{&ff}wpae0P=FYPLnT=t&w^170C8=@H)W-sscr8`Z;?s^#SDQ0Vrjw3mq zOOXU=b|73dlz zh8A04wBVA^&EE)Or2*ucqj~^R+L##GhsgQ$@ZJbJ(*Y8wJ=?h_SGXslxjRb#+JFkb zER7s;qse&dso6Uuzen=QLHzB6a3?KfISReNARd8cNC~4*c{1hIkhw%i{0&v06J(dY zVHotw_iB_%~8f39>Sm1o{=-VL*F)(yNlX4^n1o>*Iq9)IM(h~toO znT1PCVai&K+o_}0==+L1n&wO#SnP404IvA4H91a6EV8i(peBX*?Vx-&vgmH05}Z8Y zu)Ly}!?f|E0rV8KJ}<(du!;wk(2rsMwEDcUwO3H@4PE1bzR(E#;x`P5V-yHS;rwLc!EYYK z+&Scfg$d#MXD8wEAkAzDryAD`=uzKkUHKE;6FLHr-^eCc=M^}V2X1%>?8ZY9IkyGzyUvbP6;@5JrbZeiV?D^5>Gxtr<%3-I z(G_hC+ZG7jYg+rc9E{P~>^)=ZE!kx!<>uN-y9}4a@FQwmwOUY4#-43n4!;TgO5~0U9l+} zk_h$!pd|uvhNU1CCxNOn7)og)0?wRV9N5&FILs26NVRwB_32w4)nXpo_MHrF?ba|0077TuGaidN8tarn_Qy->8`xy z@?FQ0$^-1Ir6%6F2Td%$(-u}JnpbGs*z2% zk-b`DpViqMV(M~@(7+0*lh|spy=jxlCezj|vpC|i-LnpP%zqanxa9Ff7mP5BObBvc zRboD1Vc{z?R2No{(uXL_J1c%y&C*9XGiH2ywD=j!k_U63^zIx#!@TG%dYYSZ%31JP z9qL4AJ$NQm-Y-l!dnAN_?jQj{H+A1u{NWv6r8j>sLfBJy&=wSa=q5a}hdQ{obYH?m z@vETxH>$=bu|+RcCLetd|LQ$CU^l`bTQ^0LpQdQk?`jmip}eqrmtP^z--<)*!bN>Z zw13pl3%h53-$MBKE$jN>WzkDI!*BjBw(%=35XW09^KSgvE#x^*Mw5E zEk{>M6fr9}>i5mWpwhuc*(tWJrXpa|&N&Qm`_gJ=Om?KOm}b(W?czC3OB0k#(UEON)snoNs1 zb<4%loF?JB>@|*Wjal_-xo69b5n9b%h_3Tv$3B2t zG&BicL%#4PG0AnFSF13sWg~7SzrlJh>I;oXeK96U2wwzMWS{Qsf>Nc^%?9vP$*=Cb8*y7M>#Z5KQWzQ08t?Nc%FUjc2oHfK@R{VOsn1-Z z-o;bm9rY{scGGUsOt%f+p@T_wn!$U<7^$$>vkJ^Nxr4k(0PAQu$akQ|K>#`z&Rrjs zrUMAhN&OQzS-F{|O@pZ-ni2+lTPHL!vT@FzS%UAeu=JGbb`U=~chFjLgggc@a4}da%cwM7Y_>Eu zn2cJDvXc|b5VXR_cX@)c9mb?+3U-azaM|B94>KP%K%JW~DiAo+OM(@i>QfrhAvA5c zFEAACnG+WhFAQ#}I2|c$qBF@8FA~&88JA2K4Mw6`NX3*SvZ$KR&xP6sBPr)vN|#2{ z+v6y`q6(k$L}G3w6W;eWM-{$6oOFVOtDMl4eet&OxF6)*Dmlt~_G(&RfwhSXh1l)?RYJrPK-FEh(l< zELA`CUZhs=m9glAD$kEaByoU)Jds8 z?W9tpc4?6$sZ(XYpekIw*JVDVxw53yRcUt#pjdnGRp;7`8gprpRiUuf@g{_-x@YR^ z*>-H38%=~S*haES*Zq_xmjJ6zFAoDM?V#tr4?6~uEE6&a6Ppc zq&za1D-4jRW2sKhD5xvTu=Zw+Of(DE$}E&ibVo^#=50uwodVa3OW77JwHnJf^EEO? z?~-_Sy*Ik*`F4QPRY1-_2Qw^Y`pYIsVEC)+Ed}wNlFbaKBHX1(fw_K0=GjWm^g581 zwEP%4rl*gX_Fx4ix2I9!i7`YMJUaU?&#$unZB0Flgxv$gL}?dWDbuOSHPY0sqImR5 z`lxluXkwoa=Tky*#PoTnTnuudV}!FeXXiG&>oV$XFQ2)1=!HxmHPoNu z7&s_;XaEd8YRq|bHE^tW<6Na?nX65GU;0*WI#4c8nG8WPha;bn)0Ee_ze5<48s;OM zg7)|_6W;>qQ=~~u!D--;@D13xo(7Wipw(NQ*1ZruVALA8(TmgrzJx6Ec=RsM_y?Ej zq*&jqF7Yy#OgJ8j9DiXKLUVREtt9jXx!?#L?}yp=4TIs}pvgFmbW zUepm}b;Fw$*dVx=lDXtnuf&VCmf~&{hY)U{-Loo<^Q>KnvZJ6Xp!L{ zl}Q+^1*-wcUUM5hOK;34vO23_NqlN<$&};Zr|@v=&W_$lCP=>^P}RQRNT_H2=V zC2yuT_AR?wAaGZ}>jSQ}MY5FvZx#d60->2vOJWCpnh(Hz^mRXMyIt?41UZoiSXzv; z9dv85)uqMXPEdb3QO_X&S3 zWAXH-b1F}-&vH-ar7|yqa4W>7Q-Ef8Mmr=AH+OxBo zjIK>n5~Q9~uh29(k)bH~AGI42UEEpX=8^J!CW5Pv7_)L=RNGOqZk8mPTerkcG?w=~vC`H{%|7Rdb`;Q0bB_8M?|-cSsoR^Pm#cHm|1*jpVNG?CJDUvZjPDB5Sa zO4JKUgFV)0uT=D#GdQcIiG$K>=5d5WCKSV2RV*voplDRpXl)8YKUF+*#uy5`vrMdc+;VWDqP z&jFA(5J1$mBl-rh{^Q&443U8<5NO%8@P0KAtsM zU@HPx+d_-h#rRFVJ@;;aC{HNaX@V(F09v#WdG07KN0iPxi|Y}Q=7Y!eK$<;zt{AuO zu&y^Q?mHQ&Z`^zLq)#n!22d~|m=O;3$;XI3Urb3hrf57@w|~+0jF?RB5aX-l_*Zmy zCFCZZw_@(m{;H_nm!uw?)WT_^_yp%N%cm75=7U^5+n~FuO#Us@B_w@J zK35PJ-A}M6Iz~1g&#Vx71j+~yzA$wk5_>qUWsz;w=+D{1X8Yv40o4Qd^4$BV4lJHTw{T~k$fJJ`rOkBzfkHl zh?+CVsyamVJ)-#9LyREy!c=|b5Q8dK@d~Iw@%?v*<1~NAZrnJeShW~pU!fx&T%C>V;?m!EY zl26Bcr$U}#&AReATG z$mYBuB^|aK9D_vJ{f3X6QLMZ9+qg6tSUg$qKTS&==V5X(DzYo>4ArkZdNVB^b6|!L zx!y5!oC9rr$Zrz*Z;DW}AcEVvX6wkMNs8V_8od)drd^sHy^v~&+Qso3d>$HSP^rY^!QnypZEav@=rL9WCvSk$DWlD=F34ute72+qe7{^rmnFe`n~EXzPr8;sf<^19{|Mm23Kv z%O3Rm2&zoXsE*vDbCGvx+WppstK*;RBY%K?7ioJl`Nj9GU-|aqUrz|U3w&OW!2tju z5&!*-vVZ*}_5a{rz4rX>{y_83c^3;FRE&?yhs#sc50jVQ7e)w16+|pU&5qc&X=*FrbXaYX2B&cgU19lBB^@IEIl!gHOK%B(2pEk!-y?2__FE902?5Zhc%*vdE z;cWcf)q^=C`JDApI3%Gnbz}RLN9c|@>rRUF6($-}%_l%&d@3ab0RnTOo!?=~vRO9O z3v$Sg!4*&HDttmV=d!@q7*VVcU$?3f#F3i^?s!GCb6djsHs5P7zo1wKXX&vPtremr zl+R})VV$JA&f8*T+2M^&et{NH#6KAFc_IX&3ep2J3zG8KEMQHldP0=ujvh&DvK?5e zRh%NAHDjt~@2u5^V_PAdmolYQ3R7JO?Y!*^+%1u$rv5A? z?a1jmi?UTygeVI}xz`{XhqH^nM_PaSlgi6R3p-6p<(?Q->Aj)9(h^3Q#~&Q^m+*+3 zgW$-Vac&j*O4FaVy$WjGL1Cnndk(D$qb<;uYCGpir*FYwBg|?9JeB(o5y&N~#r-a7 zM^CW2DtF{2Dql)`zmPWNUz(9^57?-8`#^3Xk$Z>!k!~e}cg5*Rhi~oun^%et;J*|` zyxx-{`H$#H92|O2j-*HQ9@t;Qu`9Sy{nF^J*z!!u8S2JBxNNVtD}e656Oue5yAEbg zWcMw-R(B?;bI&AWf@E%AVJVpzM~~JfJzpR98)D-f*nmDgk@*)DpR_e^>z$=a=O#@% zi16-Jux$sNYb+h6G^sjCc`c2NnWhC8p}bxa{tshs6%+}SEDba0V1v6mjk~+MyACk8 zyEDK*Gq}6EySux)ySux6?A^Wb$8P))cl)8=x?j$zI$2ejS%w4e3>*W*@}BY^Ueyd@ zbLbV5e;oKudH^RFVdBn<(5=n%xvfigiz>Q{Gx|7nQHn>CNeNaxqcy7U?R{SBwlsd* zXwFoRPg>K0uJ1#{Laz?)rfKQ(3yursCKz)w#~U=wYaE?%WMjCFiM5k5t*wiRjW?i{ z+7`lzi_ZAod|bLJ3b($}rbb%Xwqv>$lw{)C?B-H^V*BcH2A#&O#SUle>#f_2jorYd zQQYyU%t+SI`=z&OmZLq1l?5#>X@o2WtPA=~=K0YQFAs=%FFp2TTQB!SX>H(}m>rER zjP?^&Ckp7}6>?3w;>AwnU&28I`#Z;9hlOVc%02U-pw_d9iEhe4o}(jO9(M{Q8K8V& zytoh^_WH|iDHEW$+$M^yb>7$=ej3U@(YteJ6)Fht*m`t78rn)5TG?~n^+B;%X9=X0n2Un(lZ_%ez`9OwcD`aEd{-gv4(M9A$g(ltyBu~ z|CqWR9O3k2mYl%dli}@C?L&p5Y|5l}@0v;rMf}VYN`lGPWMQ~g1-pJgRzrB@dLRE- zg0n$(gPt5rd1p2&GitOw*@0QawSIV&7Xh2qSVaqils3x{u!B)sH7*NWv+i6+R2r}3hT2A%GQ-IdXSfWiy8R!Kp344bnMT9j$QRLstA22G|1mR&U0s+%fx za7oMmOv*xsAUAlb7#ETk=f{A%3bdqnsm-dTa z^<`FaPf#n%JQGWuXi=X2!+L{>f-AHJ0tDpf$N!BQ{@se?|3eMw>gMVw>X<&{h~&^l z^?%KDgik@iaZ8=e1*nv)>a!LUDCg;V_mIVyn2&!EcVE1Ad?I;91Zv48PQIhOW4$lT z9?A)cAhRBCGdxbLJ-Tn~cRYIAe!M&`ZhqqlCNNqG2cXR|23#q@ttSQFTsy$2+sjVq z1v_ldyR-op_e-ZEG?S>97|jr=4h-GEg(`j-B?aa0w1hyQHDhual-iM2mJ$<`6I$~~z=U#GRCTbm29J9rDnnoV~** z=K2F}RgZp7Z;fyHtP6tX0hG@(UD(7Bv-iEte$rg4WeW_ogueQhyFR8F~Le8rToQ!HrqIxE^YcII2 za)QFz7*;j@6`r?lfX;-`S9YsC1#3Qd6n+(w1>XzFWW;Y?D6YdgNenlBYUo^I11Rym zcIDYt?X8ot1y(fY=)B5lwRx?pmXZ4g$I1R3E%y~$u<}iOyZMnVE*s9Ig}`sPYIa54 zSJKywEDe#$*!Y7!XttJaP?r`Q0r>C~c1r!8*c*dT*dEh`JHqe;+eRib%;Mry&v}e8 ztTEUzN9xzbz{#s-|3Be)Fc4s}>7c-d>-QKNukKrIifdLcKyJtFg;Kt!DjDh-hpAmE zGxVk`_;7rY*>OUfK9Wv39W=9vEg*fjPCDlDfIL1C8r&d{ixOLstp4M5k znrIU9)Q@eK8{kVbke$5gT9gcT)+ayYbyZ~Z2dSHNx^v&aU)RwTC1g_iDOY7F<|a0{ z_pD-P&U@^>urJiTvqKs{f@W~_*oER{Vf+oZzuGrO zwHOqiNb~P*L5FI9Nes1_rr2pYJSh}tOhwJlK#_?hAn5v;k};PtK9!*k_5HdSM{^ik zgvAXTu`43Hfxm6_2e%o*_6}8DvLBk2RDHz`66b0fjHCOg08d+(xU%(iLqhKF9FqKj zRV~itl#sF~V?AeJ64G=4p?f8zzFidIdL7q>bnt@kIH|zRQ`0V5nI#P$M#TTj$+| zd|0y(T(S__r@x~GKEj`*Zl7F3uTany9Mc}STk&hKB4M-Y72_=V!szD%ozbSq?;BIn zmrEOSsBy?}a|(M3+2C2sW2+n)MOJh5EzH`q2#HzYH)$xE*!f>xNKgOa=!4!bGyO=rGpq2lFpI<*KAA0zwYG zL`6_GIIfb794__?e?L%tzM1|&?fzzeka>lH2x`J^6Ga)Mws67oHa^B)dwafkNDp#h zG%JX;NZsV8>Rqm>;i}Lj3&m!$e0SLp$c=u%6sJF=aQCdiF!v_>k>W`dDYhX%#)NIn zi2B&ifXBF(TFwjXk!zD5;?x(*$&3ghb{`1J4h{#yzql5$;C9p^Mm0hL04oUkjBI0O zIAelU^bjd}MtwY;^0*%GWo4s_Zk0g6yMA4CeiIx<_?=ew}DH4Jxc8M62)u z0}qxjoWvglB8V$y0-i2ph>Byf9|##GyyMl zKc4dFHz;dyCXc6yjppR9O=jeSf`}EgH44*f%~`R$Mbhhd%;$crCk}atGRZrXdxIXh z@(~SQp*t(x!09V4oo8e{T|7QMk~>6PV4pMFVM#anqt&P}%A-#SM0i2mEJ);r?N!F= zWGM??P=ugk^H<40V3_Xn3d2!0@aN=N?#YD5*eA&9xxx(99B<{*G>Mz(4o`QVPe5sW znpByNeUCSuO345xxvc5d?`I`Z|M(A&v*hbRx{NPyq470LX87+e*1s^uKkrq(+VVei z)Suq6DU#%1`T3}!qN5uHfrK!0ff^yA)U<@Olz&G_pI78k$NG|?71kcT`_U$^<1z5N zg#Qe2p2Q-2pzyuYyYZZ~GsoszU*!!3tzAxdJ$_vHP;|b(@5+N*bT?A5?J`0Ps<0UF z0K=1hI;0IllSh`ifl?%=h3rbEsa>OHnB2g{nkFB~$T2Hu35tnQ4_=e&Zlc3mS%BU&85-hMBw z6%-FHaoZKK@~{l<>{Up9DEi)uI>G!)eL10GHaX51$kqaE&iS58Y(K92qD%-T4zhJ5 z=2I-I%j5f1qQX?=04tmWRM*+M3*0Rr^7s3@3}g*KG3Ht$52Ej?tZ7*~q%{Sm07z;; zt;0o`u_>pnb6DTKRfCSBU$+P0=;*IdT3AkAlG3cf6W#M#s~jK{LzV&k1HetPchpU^yA)fmHw(CU4Fs}ZCjc9h!+du% zS~-w}MN69MSlj-%LWr<4Ujp3pd!e2bdc`qwl32XPx-!k4P%{-L3zY!KZ3vH+O}^hC zGA*C{!@YwmDP`dGjWU6@c8Y}4ZV9ZoJw*bWzs+S|E1bS<0+@c-e8(EufidfMtlq+y|+wMFJ0vh@p*og0428bJrmZ{PgrFKzx&Rh|& z*|dwegZJ)6elk&wtYYK9DOum*v{{+Y?2|_x1^TlX2NZqKm zBY=YLhkQ}5N&XNBByu|mM&WtdkgUB-uS5Q8L(u`vjYz^5oGx;i!;XO{6fhwhJaP4K ziWr<~#^sKe?H+*QeQPFnH%St6WR(%*Fb}pQ>XcqM0|`MZqHaXHG9AdeCk1s;kQ#>| z`FY|3hCf&V9cgr!!efJQLAEi79>JhFGfioDexWhMu*!s2(&00L<&BuPJ~rszI9oM$fmqo zncB?)!WI(>tc?*S1O@l;>P1?k8k|8e;?CW7y~7NG0Uw0vvFb3Ti=+{#*9^`jImL|w z#4ko&yUXz7g?p!dmJx@h#Q@MQR-YiZ*yhA@)s6q|Y$;EBW{%4{O zSJie!QAPcbV~R}4I|Gb4B3O zkY15b9DT7yX%G&bXs*5V1|c%&Z|s7D8h6}qF3sH7{aiL*coXPO8Qk>_h!O?x)j-v& za&x%T~+XVvB z)Nx;FpnO`ry0js2IKEVEfJ%#O^qT2zd7~VTLEXQsD_OmawzSXCmLB<^ z4Szz4!{hcCfQd6${ESJY;8gfCsmymtQLNv~-ONK8Ea>;kksW_ki#}7xF*s!3!(`rZ za#e2|@aUg{ORY5lLw%GGi{NC$xwB$Fc?gFjR~wwgF8|eEtr;s_saZWzZ6LE|hjbae zrwO6dsz9?gk7Ew^P03JY2OP+V{8KMV&rkO_6S0_N zrFbs8f*6bD^l!P4@`XTfMYNjAONeBs&2jHlIT*p~zIh$LM_BtWA^IRtdh1iYI8iW zSHH|)G08@#E=aUDFLf^k^@>+3)S&b z>7Q7-byvc-k1dz1{WS=)brz(YDCCltLWqK5V&Fw*In6@nIAQZsPZAp0;RDgFvIBUu z;e!nLn2`{u;rWg0;x~G+&R)XsMntqmF?VN9#CaZIhxRG_IHu_vcXW^(2$JIY?go_a zU@FGeN3M5eLg5wg@4$@aZ700RVKV6U-aBssnwJCfdG>;^w_w@!5rQQzr~wK3^>Aw? zUGok&9}y@oeFG6#H?+Z{w$KyDv~eF|kCPYLepF?hKrK*)k6lgRp6D`;y75 z^Z-*{PA8}p3B312idXH!lm|gjb;Xml)0$AKdqQa?aBaXP`>%?$Z5t7M#ay%zh3`^7 zgm`jt2e^niCX|T~CczhZ(R30g&b?SERXUg_UmXZ!)4AVTXJqD|AWI5_N`3?^)^$62 z$fjZ?m<`{48-pBh%o|6r3Gxa_K0V$>7g;AYaCs>)Q0D^esqKr~=Q+&VfBXIK^F!Rp zlTWO#3Q+%RhWHOt=l?$w=Ku97{Z|zzYx~RGe^TEVQ5V~FS44{AbEQgU1i0SM03Z)^HdwMNn_$|5#jT_vuJC;;?SJmeI;Y0*Tht7o`t_bUt+e~jD?EGU6?wk*6?e|$e%-=nBlherBeNoB!hv<5+Fw7 zk@<*(MP&)`cCY}8ND;3`-o}-hifn}>Qa>42fLf)9#Ms&dGXw66u32s~fUOgZdo%o` zR-~v-zz1ri2H#;lWN5xTz4|k@l2ra(E8dy3m#g<%W0D7~o5tge>Wm}kM$w!b5vnbW zBi!No1zAWboHw~BobviC=2?w}sH(j_`7`!M{B`o4TilswzEc^=h7Qt8en~%xrp}N- z0x*;_jH@ZY61{>usTUrK4H9c9ATZ{S`2Hxn zf+Mp|+;}_TK$!9U!GnigA*lj5xeqky@oJMP92YSoOSa zEaaZh%N~t?&aA#j?3fX$3mwEqxiIn7QfBi2~irKWBRX`o=Y?MqTH?dSdjpR&UEvpFE2HRN`0T)bi zy3ICb*qpgzx=bJ^Yo}e$+|l0(MSw~5NARadd&})}wC$zwp9)HIycp)pw4E4!zkgkI z1(Dz8wyQGe9VlSZ9^p|aFxe%-*IaTLTBK$93N?46$EN_lb7h)XW_)J1a)#sAUL;Q`N*h4AMyDM#-u-SkyzNFcev!d6aTVM4ox7OvkgONZR;iu8Z#%QQCsUYH&>6V-`aGOHHLsu~{( zgWuW&x!8}Kpc|*)Qte+8h=@%>N`blU=2!-@<49PW@6oxpG~DyBO@-wA%1OLX2MiCT(;A_Q-aat+JMjbWj_LtQ9o(ft(+@J)V zN1FoUj}!ZAMUFceni++VZmZ+cbKO+1+Th|88gf#nyAz6$~4M-9;g5FBSMS%G$zTJKP|^#kY{{eWmRHzZq;&* zHIH1y8O>IsNG;!)W>Mn8Vx1(VG96czv#R(~>_U`MXPj!=H}riqN!cj|PGyxa>rhKH zaLvCan`$FltWJ(ew3;{IRJvrg#p+Pjza{tOLe_whKUj?~zOJ^x*E-vcXRQp(OSvFA z{1j`y4unX~u3@{39B-CIGm{)idA`u7o?Dh0HCYJR#IH;cWy%8QZOU|?Wu8vAtTTda zd&TXUhKwS$#yaUfyb|4fXg;){cFMik8Js+e8@0mpx3-w%ej!DAnZ^Dw8R3kZ%CK;8 zTZu7hi>PflaC-*HzCPCYxS5f2FgAutsSo<5nA}tutGV;6{X;kOqm;4=W-EBEEXL%+ z(b7o;!SK*9LoXH%eiPs& z2xM_s5PWZgmGVS5;2|u!nv0hMt?O70DG&rd{t9yf@{07F53TFFHXrp4C-mel#5ct2 zoPflun!oC#Z6S-KZ4vC?WleIZNz1lUZm_nomt+6nD(#-2q{5Ta z*ecjoQ7_VMqlQ=L+DBytfQ>GU?MPg$)LoVmhj9{C1eaBmj2+{iy|(>GkNCJD5qqn9 zYf&+=qVYaIBiT>)cI+JV>4M<|JbL@*Yb?G>LuX_vuQ2C#dT=Wk)mVgzHrK#9%2>QTo#+Sf89NMkG#QwF_(_rSQ^WGnJ+Ud#O9iAYHht7a=8J>EReAr z0NVptR?2~b^B5ntNEDQ{_gu$s&--=8pAuk1#9FS{J2o;m&ZGRJx^Xz5*pd2?21{^W z*POkQ)}pJrrBYD(FYmNoy^b$$w$xf+&o5(k67Ag)^VCrVq$cN%riXYySX_S@ulj;IK1KS_wzW$Hv6%_&4wlFTrO zMW$P2NM>UQ)6i46D|(z+YAl?QXcM{-aohHy(?zDKFPGY5ONkMnR_TO8bi_Q7@aC&5Ijx4<&wrHpu8t5M z4)d{(=c-S;-yy$Kpa60#t*%VLA;ye+{~Ck(h(12~_Er`D-50$BSD#YogJ;3#e4Hcz zOFL`V_~C;P2%EPm&Gjl_879;k)YHDz%~zJwPINJ@E+)bru$nI>-Md!Q;>mJxKs z2jw~%cq2>oO}hG$HmGnB8Xtx4@HUoWh+S@qQ(co1LbllDR4)3e(<%fc^w z>-vO$DB;u-{6@6X4E0DnT>NT>DgN;v4h8k>W;+sJj&{ah(1!WHs~?pA$D!aK+OdB= zHSvnF@;w5mX@NJ>A^urK;FV(d=lLORmS9J!@I9Bi9<`{M`La7Uc-qhDe#Qyn zEIR|3A!$f9wQlyP!=Ey0+|xQ$%{CKhNT!-~K*bWHo*Iv<(6U;nR9z@+{Q?@kaFFz% z(bYn%n00cZ03Y)#(obTGj9A?1)TlE(CXPb&;W0z7bgf8XxyjrMj z|3^WowNIi?7nYdhS*c}uiR$kly}TN=&=>EHdQL(i&w)y9ol*d`i{{wJ- zx<={(4RuihB z2$8*}H)dx)-_spG+Z#JS-`*g8LZnL44E@xIV+_bgh0GpqiiDD+8I|~{*dxqX@s~YP zZ!prp-Fj8n)P>$?t*1&i_zah1}w+NFi2sSQma(0-rQ0f4q$1#b&zG-fUHe3 zwl2`K23WZz(awv`VKIj{z^ZcPE`|+roNVFK2JU=IjEDQ3ya7&cYlVE3?jo(0Q%>;D8~#N1 z`Go*!rTEs?ZaQ35X4CWDp1zJ<_Y#LMV%YLWHAUfVjL%dwOUZrEH5I=hT;+Wp= z-u=VYI|}g|9o~bZP8N~hOiU6SGK&7h4(S(0cX8rhK#6}eqMHw&$RXf}T}p&O&NW#K zQHW>=TvUp1fV9Bt=zB$A76N$4Owz=GoZxaG!Qb>5NU#3yiekmdjF}ubV=%$QIS8lf zlCSXMZ&d7NsH!wdgCYdWYlhtXD+8H%WOCV&Tqti=S+>{l==#vl#4W*CDcq}C*+XNB z2ML?6)+6J)a!Y>>Qla~5H<4afv~+spC+e0_5keuOTH|ut@mA__g-E}d6K{+s+wMxx zwlbGLUwRvX++#vBaVICFNFYhu( zg$Vmsi2Pq}od4Y1CFtbjU~cIArIk0Z``mzf z`lfUgd~$(i@Fo!pW}vt)Uluq9>#9AJLL*)VbzX3V-DVz}Uv<#X)IQ8BeNxT1+u2z3 z=ebtYy$7|y40e#+m1hHeFkh55BD2r?2$yIR^Rscg3czUtEF1tSo6*GlGvVotNd*Ri zrDhqP&qww{MKxED&@n2idgGE(YK)Z024@c!JZzG+ueKHzkB zsVObnkb2T(S~os}9t1sUcMA;up4c~2sB4Q?Ah6i@JJG;F4bo4eEyu-r2v-)K?igSR zPdd)oHe*;uMI@2+(2qNm%80U7{|S>YzW0YyMQA96&Fn;Lt9y?=(b!P2zLrO(mhZrR zzN6nV1*{}yUa4~+>!vLzPs!#lV8wUhIn)VY`KlDOfd;=M@VhC8jefa{dxp5wzrmO3 zJp0dmGdD*y!z;i;P0xP9?a!pJ=D8VwK=o4yIoc&1<*k9Ec&3YSf=01#D70_zdS+IN z7tT|DLTwp#T4wMnqmbp3j2$GUqnIj2^axagUe97O&hAI#y2ncvhReT(U9ME%%jm%n ze!Hh6?8Y!^i>uhd7G=0ejzF2)1@}n$`G9yhv!7ZmrC@e zhUxwKAJZ8QfMvby*DAn1l&?$vf4l+zyx`Kt?yj~Dzy9YX5VCdq-&*k56J-&N*C?E& zhQ}@1y2}!dF_;Di71SO@1`a5oSlu12+cnj1WNw9!AST8Pn#LwMTj1F;weAEhi_tQL zKBHy@pRc`A@Fw_9q<`ejOfnpLwsQaYJnm_G!F_0RxiQUsx!w%*lN~=mAu=+Mb5S^{ zPvv`h68fL)Eh{pUC>SE&x+TW`C}`mxPNEbvX=%6yOb3{WAcas^Lwm*UG`9}KzCnm? zijpg0y^@~Mr#wtOBu_QOOr@)1M7@5~J}!!1eAG*P6u`;QZCD~NBz>i;lz^_UQTdq< z^nG-9?TR~XLT$K;)l}74M+FM<-k;<=x@?mvhI^ytyMPS5d2*#SXao~vt&@NR*1nb1 zxO4N~m?}$#Xvx7c+)vZ+GJ`?n?yyhCv&a{XdwWd?Hh&i!PR%n-p>4&OYuqZzHo8OrDVh5WvDTXhs@tE9|BKiW={acd5T0Q1vjst~zv2R614rQ?L7VwFBJmpM*^NHO` zb^*nW0f{x~`#McL!hgOdSI8awoJuH-Xn?4zv|)jly)~Y?YQ_ zAp;kG_H$iM6vQQDNLZwY<}NQ&8+iUYmmm&(kANZ-Swxutec$0;d{#LorXSgK2B2aO z@6|xRR}o#P^u{RF3;UKX0SA-lp_s5%Yid`{qHN?%W7K3p^h^86_&UD41gSdwE-9ZX zLfm!Ku1Q^rpYS{AiE7lGQQrjm5w2UdT61>9-GuuiuTgeBReV2X2=!I39p8ld>948L z7Qwx|0aakjWo#5V)QCRiJ0L%1rY+^k(K@?rH7Pw*bOseo;zDrTV$Jh+T%X!Q_zC4Z zrp?=Xne?W(XE;YMlBT#_Y_c7t6gl|p)#R68Y)YB}S9=1asV@HBy7pg*xAi-z+9M>A zp6R&WYKZJZrm33PJJh1bv+a}#r=%N{zN1{w7sphT$be0oeU4EVlOey*IDf*PK17*N z6o|qr?-mrBA{4NU&XnH()C)NBXR&6dyBwTqxOjOAZWBHMG9L7cn)nH3HjN7>b}gPFhOgdSlm;yA@3-i=TCLUxRW`hM)y zI%zwVxg{^|kKI&DUOVQLy+I>gcZS^5cTCZ~+8u>fGGo^?ajVen)O8Czy5f+GM%zkZ z4mYwi&5X!~c@Rj!N4vGjP?yx0C}fUGIw(@7OW$NR23GS8H1*!lA5RK3{KqBu?}Cfc+* zNBt|P{0X2h&1nfWsBg0Uo7eJardQi&vyCz!DrtQHXl>~!pnFC~C_LADptEl39I^^f zw~k6z3*Z*?70+WbHflY80wKDDFD?rU{NH}U6` zijhoUJMlkg4OUamqNh4q(%J$OOYnE(_vLY2WL388D}c{sTg-^(9ni;+rhFnCz_fMj zr{~fkBHlnR=8$rH&1pd)cA^zn<}$y1eL=8Esof2y!o8igmY3ECwK3t}1K%Zk4>oA#<$ zZP3}}1L?_gW*+kT1joHJ*?`>6w2~6^`D>WfUMTny; zzB96$*$Rit9JwmKP@l+q(F>R{wxIgX@G|)6hSu+4?a=v$j`q)O^wR39+#5DzP^G<4?LkAyp{;w-JtQt~$s5?J5N^0)g9fbh=Y zTEh+Px~ohwFRq)9dxKYWQc0^5@I_T%#9NUgNvw3GS>#VP&SFg3wMVL9v@J*xz@UM} ztsJI3A*F{j z>?2*oU*`D8fHx{mxP1ERK z+c-A$KcZ{dW|tRAUhhx);6$oy?ac?-K7Ow?9z3H|M!K_%Dp6N{_As$!R$Z4g4r2TZ zfa^ACZt9A+>qUC;PI@$sdW9k5-w}~2cr%c)cEx2ZQ*ED*Js#_@G$FV^Y{=n@14`xqM1G z0c8#8k}D}0FR?m0lJ>R;f!(2oHBy|uQsK>o8?rU98O(@dyf8JY!(`JZ824-ve^9bA z!^VV=`(S;BqUun+OHZSiomyaHS5BszEa4p-N3uNs4`#y!pYwwS65HpfWqYPQLtL^Vqa*iBqhAi1zh~ z&nPPTUZhF{R6?q@P!&<}>fF41d@bL4Jh!29wLT~~q3?WiHE}uk^k(MfPSwZv-sukd z_A?X_t_QKL1{!i(Rn`u+E#(Tk#}c{`Sx?-JcN;!n^}9GUSq~0$Bg%$|8}l}80QYxW zvbOLmm!9+hSHuhAHQA=1E4iN5@0aAbu!cgHL~V&zd_C;}uit9}9#IayKcYmS;1i}1 zdih=vZvP1g`c6R1BlBbjA_uumay3ofH~78K|H}SJ1d*+mqPUkt@ClVi>WO8WvB&g# zrnQh)gk8uL$M$UiJz|H%6Y}=xwx)G=WAaMqDxwrNM}yM8o$l>fs|IBU zG9+bK{b^`w2i#H`=V)05r8Y+oY~Sck-{=QKAB&;p?4}oLw~<&kS6QiiJ2%IE-sLN< zPZ{>F1*j>^1=BRpM5dUta+jbxm3W5xcxp9*A8|692*O%w(iUR5xYcAG)K!)3tMo3+ zCRr)epZoJE*0F{Xt5OhkHP1&gXwqwywVW=bFrytBsf@9dVk>Vy_3_bKKic$4$ky-~ z7r9jX-t>OH_PlonPqnZgsR`8=LR>k!=mNTsm(^xpr_W`1^R&NKnKW3O7Wf69F34FQ zWN8jNSZ^xEe9}gHe%+8t+v5Vy(DOxW7nW@2;>YV0XkUX!_ zYkrogHmy*pjnsRN#u^UzhV5+GMZ?8upg2&hNWH#5yLucc$^AUi4}GrCk)@e%s!Yp% z_x7h>G6t34{;!FADwgR~k$!&8!h?c(T!*(->fL`4rdVvuWJ&|u~2iT%?2tUzndj?#h_y{}^ zZHosGp!f(q0k%y8GEsa4pUAe=1N2dRgr8`)T>~~zJ_Mdfw&er(Q3ecXz&)X<4E&?W ze|^U`h+z;-B0mbi?IuhL;4vUD0NSB#=U*{>)51s?^@az%N<_p3b^^C-uO1QKz&@~i ze+O=DUWt6q=t~Fj{7FOjov10{MMs=Ns42q^OsELOi>O<^h=K(XG(b!!b_*rz^-Nyt z8{0K^qCCZ6z3xWy5JmQB*`(+jA*qNlCVLoWXg``_aGz0=x~o)cG30_48!=8dWj=$MGc+Uu_NKP zUwIJa??n}738{y_*FWVVVO_q8^?_S&t7NhyNJ!Pl?25L`a!`?z!BO2jnY9ivLjEDu8ybu-@~>iAlFB2KbxnpH0^?-1hF~%>xlD(-Y;^YkgwLHcd`8r>V5!^>gHAh?$W)1+bH2W3_H;D4) z)p3>@BfUKN<4PHmO8DD=P~-g{h-o&~>x0|=$l%vA_Ho(m)k3Rk+14QXp_AA6l%AE> zZOAb6G=lVc3kg4A^)j^l!`+&TzPz|^>X3DO6P?L4f)nq_G=Pb6?9p^;#O$i1U%A$y zId!Ppfw;9zWMw^RbS)`Qe{g0~C)>7iq0;U?Xyk=az7sug{eqOONzr4C5=T?fruc77 z1J{TJ`^Z>M?2+C5dPPT2erG&)@F9H(|LB?R?n$MlQ#jW;>xo0Il|yd8*Dnq$rnep9 znlOyfVCeZytd0sZ1I8(~uxMWK&>mFhD~F}TKm2QW_S@a@D!k@ttdjqjD*fHPD%-uX zQv1tIE##yU#IXr&f1dNKzq22CgK~wN@P@DVv3R|oShF|ic0=OjPA~04FYm*v-w{ui zxjSsTHA-(ZEPu5}Pcs_3k)gReGMO4^?P%AG7M_{(%wy zZa&#LeP5XgVc)Iq?`V=8NpPtm+7>=7G5T70 z{;&Q^g0}ja3aYOwuo)E-l4hkuRoiNRBVxs3UU0>L94y)ZG8Rsv)bRT^B_?QcEK0R< zt$K@jk52uKyM7Ga7M)S3-@g1K`x{sSTv@klNDcI&aYt<(@l(I3EjX05>;sp{HjA{!TTIMSSr(_X>vh_yPgejE zRhO5}Y>N$+;X2GNd;Fn0gFo17xzI+!a~f4^6Lm?fo{F?SI<=j2SS(~t1;uZe3cMntm0yF^;DKnxdOC2SSrtrusrV)F=?n@zQmh9lh47o!Dk(*G&F^xAWlpjgu0}Tvi;%{R) zl++K+9^Bg*{90m^h7(8QrYYu5Xe{bEQ)CUb`kjrm;|48umqtpoRCjrwN*%#}2a>+^ zk_0Iths$evJKwWXLZt${rQ+8}>Tk(xrqV z_v50-Vs^1!_1@==lrVu)wv=lau$$)4De(+aC}TGQM!f$gjcFKw5E6%AKZ07wL!)%S zv5zmeOraEEH=-uTNvgy*23X}VR?EZPk2_DhX_9acQ7+)zmyEt)DLmVX6Fkp_uUqT%-L6e6&M~^2P*!{%>5Q!w5IWzG$@4ejF6%K3TNVZd?$@zHzkDVH|JTO^Af% zZk(&b$k!jiP5n-({ZAef-_=0++!r%dndd*`}d1J-j@4a>)vd*O^S_>_!R z(@Zmz8<(QIwShYKxP~S>A78F^T(hwOCu>P6M=XIyl1|ny+Jx|#z<&L zQpnyKChzg2YS~Q3PALnE8jsbah78M*@jzb>Y@{*@`yZJSBq8$EWRZpD3(E)LEo{0=y1P@lOS+Vj?rxBf?iT3|0YMOu zeA|2Ua@_YEkN1xE*BfsQHf!xM_WZs%=bAl#zi-wZ59DepeGcnR$r`~o&J%}8?W<;- zD)sRmnwcn`Nl^^?FipJMFX2_#au6d8#IVZBF5Rxw;)LHlIE@YJ&{J+Ku-L9Gu4H{z z8E_N}b)ndj^$Lp=^B!WHMMEd4ToLi!;~RyRK0`Gr zLZpWirjAM?5cOSt*p!t3#Q##&Oyi&>2^&>L;}pU`(#P@U_=5F>yP!{x--f4K)kHbA zND_;CZEbMRdJ63}%_dU9R_Dd`U@Lawh+%RIL*CcInkWz5ooe}7q5!409WP$a!C0(x z&WL#!MR{Xn>OGz(BiU(uMbz7`P*Gf==L&5|p~kXnq{f|9DbG8Kn7c5@g}&&gLFobW zJpPc~Lrb7m#h{T`W3#n~ZNo7auk$j{-+EOVZ7JpuF)jX(Fpc`jFn%D=_TkJXmitt` zs*tS*Zvaj{cY22|JmV@QJmZ=>dTUe|`U~$cA@Uc!-OnXfl+;hxFr~{6MuatE4(+de zH@*7qYsVhyYUVDM0SG${r|F)Zvp+*W=)6XM9NbB+op?ylED%t3W)VBuhJ~g=DYaS$ zyTH-BHxGNY>R@VVmm`r^**Z%)J|x@>L>NX%4B0`=Ilz zHiT%m8})|eZZwMRf(8=239_yY@P^+#AeE7ZL?ALogv8tq&NgG1#MGYXv)?nz(8y8S zN`_y=Jc5OEJ447Vv4YitUSMOWC^VqU{WMtz^EKN(*z`Oh_(@E1WUryTt5#cD2CNb) z!IGdwvi9^u$yVIRtYhhBR)I1MAMr39kug%9c~8qAJxI#e{8k0Frf2=+7Bd7U_c(nA zQlH=v@6>=(0L@Wc&u*n?U;N>sI26^>mY1~&U#`p+I1q^#U{>@eT^C=G>f1vCEvFfarT9%W6q%-uy(+y$Ajbx?~fyv7aK#(Oik25~^?q&Q8NqGvcC4=GqZCb}6zkm~TT=@ZeX zSFdB)OR_)o#|3-Azn`6Oy=U>U6?yKVMV-$zLFR~!o5ZN|xzp}~n5F**7pv6={sRD! z3cnYz!`oCB)iP@>081woGQZcz&j{;QJpJP+)v~6E@Teb(+1R&B96I4l^7bWduY|8jr=w$p=u~Zv)X4{ zBe-RAd-N%hqpTJ`2BA`hCD5B!0+xd_Nx!j+ww*@9lg5v@|HXW}Wkb{(z@orX$UN4& zImlYr{FRiC5D_iulQuq~4!txKw%*-~3*NZiwG)C(Q(8O8W~d}KQeD}801>WE%m|_m zt*f@E@lxCxX#W>joEzOv>@Vy0&=7et)`a6I9H|MjUNyB-;2#Fx=R%9kwdLIRL}#rJ zQW&yZLfND$l~Y}zy@0l8n%i=|)iq*<-L!DSvuhSHn=M=kxu1;_oo%#yb$_gSCWvP* z6PZ`NaST(;foa!&0?i{h^_EGOYb;%#7R6UvT}bMaV$(RR$6+epIgl&VHxceEMz~C~ z^a?R3fp8m$$nIHy^d$pD>9Z{5Aa6bt|0};SD7)x{nLd({T{QIJhEOf?a zkq9?dkM6}2hK@H`{5M3Fh;l00MB=Q_KHp+7L( z$*Q|VPRqI0E_D_lJQh4@LM?!6%HVp3USb5#l9Fn%thE)Lmf>U%{f3}xrJ7MmtfeZ# z?hSK@h(We#D+4Rk5x>Kl2W;mt3-uka9J1#o zoB=!honH@DkK%iQ&B(MS8go@`&$ZE|<$Nd_0!X{2Ta$?`#ou&_x{YWZjvkYmB3yt;ML*(;pngpfb&yq#n@>a)wIJ)F&lwk#r_W&C6{v=r2m4hioZ97+Kt!2g^OHB=r zxmfZ9Mp7Cy#ugg&X_!Vghp`g2Hf^QJjg_UGwSB70cm<4z+Hv+RH9cvqmBZuR8ceug zT1-~Ny%rzsOgA1RO`gFv%?B9)eRe$h9vPcEUMT^49I7bim@5Mf<03)_;LT>|+-jbM zU6mjQt{@izdy|nXQf!fGg4VcQq}Y$)$$O^4a|OnW84`;QAU|2t+GH81Xf71%;6gw4 z&rxxzD(d2Y8L15dbB*<;SO zFCWVucbOj`aqCT5Qz+NX)vvSeHZL-sD$GEzGox9;9X7V{2FCCSdf|ab zSky;GdyWAwwox)OPxS+&VVM%`!Q+pIuL|L-cAm}K?p1D5qNAiP;YTLT`!}a(MDhSu zUmAFRO3`wD*6kQ;RmEDOGKI;Y!-V{a)de}tmjZHfl;=tta|W6R{t?%zOlI$>b{i+_eN)_yQ?6$3eH`2D;3bgeAoUG|q26cb;Oo#9 zu4eyQl(!Iwjmv-&olk~)NN!at_4n`gcb2cK~Uvy+y# zjX+xax?gaU92{vm!RM#1S~6w_5ZMb0ih~YYTKc4%N=U5-wVf>- zS*OdPNL`R2-OGtHDS@ovG79kL&$^jF@AxX<6>URY3giDt$6PSwP&?Wtcg=szkt~Fo zvSZ}ga-xnJ{s{U=EzXGh`$jTK1M-y`3N$mw6`-`s0QJ0}#S3fHm2J>YeKu~!X^?J3oAui{^E$#NNMdLb`?{sSPWzQnx4&%h@?GXLX3(q%PSv~S) z=nj`W7Y1yn4@(~re%4tN+JHr;y&Sv$3Jv8n5P-^PsyFLCcMH*T_%IGj%u92*;r4A; zg%2!HnUFwrcxd%J_&H_j<1=mEv)Ou5Z8YcSJRCO+FRFS0kEx$EyBmZYeF|8IB0!ZK z-#v$NCk-IMTp@8pjPeS}B6)Yb`le>7-7nvMFAD%Eqz9Eo{1B3ou=CdL@lcEG>j-uo z)#4-L82mYSGYcGz3T#nqJrCT;q!35ok_`9}WTOh3UtfcaigJjPAGmg{Dn+b|l-K4h{t8u8fTU3xW}qTlgO3jaRw&Q3*$ngMW~$(TIK*N2*FJc(0>K$WSycT~g9Q>BCjP}RT?sHkRz z5a?6*F)X574o5IzhW|67N=|1B19ANYuT$=1>0DL|iVq#M3Q?Tln?C4LgEk!{kLULc zqw3UsnKlY32%PA$#~k3zd09|v4~2!!`;p^6*6d-VAdNFk^r;!(w&bs7xMr;{eA$t# zQMZk^!&eG6%XAMXr&u@* zak*AYiX_<`h*`@p)XHC0l>6slFSHv%k1#a1NkW&=7iXAc7_6{wM-Dktw{_rl<4u=d zPZ;4|H3=h9Bu)iqmf;1lGSRyBD`jPtd5J~f9dNg{5YRqssihLTxFnYq#!(9-rlf0a zZ0>BZe*_gml*xE58x)J#(E4FjnkF#t7Beq}J4ohkR+SqsHK7X)8 z{jyV zyd!uFgP0z1qRc#-#t)Atz4cEv=Zr32`pV1g-URD}S4YMk%tiYbaG25ymQk4mi4^fx zKNGGTmVJ|#-={DM$ULYWc@p7XExvrSj8B;oDk+!A0DPG|aO*FZVe8-8c^e0qkc*Le z#fwLs)a}>%_#Lpa5&D9}1b64j&+E7B?uufYpdp43NYCb<%tZgQ2K;-7VGnYrdciR} zv}rg;#ejren1wkHU|3Nq2NubOiH^&gFks3y0TZ3bW|2~n)G1X)8zp+!84Z9fC{8U z-||^aBR>q`fT0;bm(-z8Ohb|^2`~=Q9|8>thCk;k(VNz8s@6hKnx{1KtB>{@w$PKR zes;JArv{m|vMth>+>`~90EHRSluA!~o3-_t3^Mbf{@CQJ&=Q108JSpNdb7ZXq@~)$ z6X|vqotlKt21mc<*9i0zad%Eq({{Noq)l%k@KjlE)O3U!5mtqn;TooC7St48^yxciV5WODPG}F<4q>es60kzz`04x0=>g3C2V{& z#FZfVQMJ1kj$C1j+nnbj%L*mprQdOcH0y1cu2G|9|JY}ho*MKZ`n5ps-mC+u>D?U_ zjN+`}7{LbaN~O1oI-4R?v1-F1mS$O4bO84D2GoZ$m)KME6yBQJZx>29o*Usq##W><27C5QyP2Qm25ne?_C>+@^OB!e%$}9;?CdA7+UEfC^G~dL9795}~X5L8>f}A(0#H zS~;NHv8fg@%y7bi}9v4Fuj5mz9^Cf>5*MN zB14VNW)5MBXhNkpafiEQewt2kWnaw-=b2o-M0&yr?-^=-Awl(q1R9g5%g0lEf=~$U z($+hRPrQlib%T14$wnGcZWV6ZHykZ6v`b!EY&?VEYB4R7I#& za8%5y3&lL&e^C!t%7W01HV(w4kyOrmN@(!8eci#%jiLw+pK z6h0H@g_>v^dgFVtSiUtKc8obR==%=JVqMYmSq?r|h~|kU?ezVoZgT^zObzm(kZoB} z!h;B8h6=?Yq+`Mg216QL;DQgItjNr~jrGStfEGoX{gWwkUse%vxIEL1H%na$m`?@< z?`QbK1{>;fdZ2`8lN$=68eo?nzKr8MeeClE(i4|&9pNemYLeaJO=4aXt9F;u{nk)w z9`||2;!vX3yrxZn>zH2fqXZ{*_k>_!lqfu{Q6Hm~wM;c|5KvJwE`EDTi zzMn-RQ=|!K)CBz-PPl*c8ww7V4x-j}mb%|3rb8Oi|s*w2%9F&Xq2^H%s) z*!m<@*I88nO(sv8FwOXr{np~;{N?4sR`Npn&BZ1!gyT7lx6(G84i1mxXn+-(%=wt# z0(u%^TUegO2C@4GbH?=AJYy&q>=Bqlh|}3vvyX0+C$q}%@F^tMxaIMeB7}!;2w^D! zl-Yo6OH0v?41b|hXd&N+?J+OoZB#psPuD0;*#N6BXp9dI*|$v>J^(UkFhR$6SPlc& zAaiW_OKJ=iT2jVJPN@pyR+AsI&%VKLY#DyoGW}u!vz%u!QDQ1ZEmCk{wB$o;c;=Lu z1Vc_v$%o<`>Y)#h=nQL&!sE=Q>?dA`ft+~Ris*u@kj7MM2t_=(UI_3P^N^XZHJbL& zPEWw^2SboiwWTWpi+Js2B@yz|Bn^5J1g}i@#TVtqhm`g74vYu+!>xh&*G7-Sc(M2> z%(3_Gktre=VV9fGRtovKIuPW}atyX)0mFHt;7^F=3y^tMgqs1YG^tVX4m;4MQ~mh! z6kk!`>*rpfr=*0-#8f|FBZ_)I4?VoVB1J68;+K+{i@~sC5n6QG5l<+Y$NnaHLEj8e zU}dzfNE>T3Xc79FFK%}TVA&H7Bd9vxwbM0^#dWK`g1l)Ndwu;}ck%dE*xwYUkwxu| z45(NtDD$|omej_^ACW%gqh-M6Z)9W;8l;r135Gt1I>4oc!@`8!DleVEtj=% z%!u0I9omtoVt(Otr;pRb{T0|~*Pyq)vJ&bdx5D}3N4nvWd}z?Fi7-FdblW1@vPn~% zfUenZfvtXAxG7`l$Ls&<#mAQwt%J+5&Iia!PwQNeT!7awL#|;JuMRB)xOMl;omTfQ zo78zycv2hZcwvN%_|FvxKU!aZZY**2;GvPG#x4lCw*-;--jW!_guayz6Jf+-m{*Fk zsakMKwj_K-ak%r5TJocT(Ftg%19&VqpvlL)^4Pi))1XST@oMKr5#n(CQD9!)s|b(4 zgnq*518=+7uH_arx}eJUi(})nleHVtxH7g?rb-2TA?F zRv9{0aht0rD+XnL`FQ2K5>Zzz&$w$8Wwop9Bcf89j;-4M$*f4{)|Kpi9o!a^O3fAK zxtiuRmj6dgzWmKS`#8#An*?e^SwEU5*Q!A3sD1iZnXkncHg@G)R-;pC^r%821V8n_ ziTW;eTuvfk(zTY6F8V9_ucaMDA3YD_xKB<0q}@Jx8FxSno(Xje0$g(c>TwHUfu#{3EGd4n}>D_XDX)YTfXuECYrIzpamQwoq~L$e>h zzZ~^}4~;(ih6`fYXn5CEchfz1#Wn%TNb=wr*#ORR!aP%ZG&&+o9x~m>39Dqqx?kYC zwZek%mNGnva`fC1bcu+`sD_%^NODSpRljWU1*4y7d?Iy4CXkg;B(U3-HsO%}AUx!D ze)G-)EuzCZ{{q^VY51N9TB>DyaBhf~9m{ZBsGZv~XQ1mmS$Q(xXm>ceIwHMmGQA8> zWQR#T9){i3e@jVaQ8*d4sU@8@w1{8U9vVT+b_9iHX}RQZu`SCyAb}!yic7OZ4tvX^ zG(%o(wLj-s0D<{VHi_ez^las}LSn`~0A^1j8jmqMH|C{E#X`qD8=^T&3PB69a1Hof zCo?CsO?tA&&%~q9`Z4@Jvy}|%RS78*(P{T2l?2>yb=+#u>lSFut|X!zXuEP(DwK7Ew*ctsXz#N|Aj**rr*qgOpCOsNWX zX<5_!$swxuH6X^vP?&ACygb6CJNP{^n;vzIrR-QFnL~NJ^9p{{fbo^!Id_X#1;Nsa zghv$rIhy+sYg#ws6;krn!w&t}Ez`k`?|&BeW%ObA;srFZPp%?g6jZZ`O-V;`h?yC8 z2zX0xj8-_>cP;%q->ILtwV4Oa^i4o+y?nnlmWRZ%1g%sF|NT8E-W&pRrY$b&`IJ(n3YnIw_D~irovuiY(=4}& zM}^ND!bG-Wlc9A#vr4BoZdbFTGaMzaNj)=5Y}J^nvALf`fF-*fGcNn(qlqztAY>P?F0-~kh# zCgf3{(4;5JV+c7^DGp{bwZn1)lts55WVXR!3nRCXE6f)@urk`Re7M6mFt;JhW{w}x z5kqvjx%w29RA$zSb`LH-uT2<3*t=MDw(}FD4R7POZrVOgvSe~rCcyj-+ ztwRVQihhvUpimdpS)E+ZX4+RkSSh`yA{cLcfaRrG09iC68*a?hVT}%MVV{77gE|n+ z@^h|CiYCKJ{nB#u=0RGyr8uG;Sgj@@0u4lz*Pz3D6U=&5 zY0(&%vrnsgNsn(Ga-J7@e%|P(NpO>7n<#OUNKBAlDTTug-I8c1u!J|^IM_5w+DD>u zT;ScgSQUw84ZmLadhJwqIfoP8Ft0&G=dbIXuz0{@ojQrVS-|SpfMqik0@v4m%iW#k z^HIO&?6@7fh)yS^T4qr(n-*hzMxJ@XxD z#|r0FZKoB=$qSSv!f*O`tTW&_JC8=ZFdPu}B~H6GB!^+1{lf|^z)&&uHN<63_+o3}!+F`H@BAF>IC(j95pm_#N9 zeQqw=PSntb#`-CTgY!a3+7?sy2ZSd?le^*Mw(1~7nML`Ent;k5z7ib)j=rvvT}%&% ziH~A+v%yOQ>SuG%28omCyi9Tom)fDIwDx+zfEA^4CP*!rVlYD!jm(EkfZ<;yE>!0$ zh(9TGzYTz1o!F^VDYflTA4!m#;5z?~!I#q(O2M2;B84U8opUz5)QAT~MjguZw z|F|*eTiY2j{192Q0sX|r&f3P%&cW2s-clNf;46UIf^ZY$GaRZe_<%Tz(SKKO)R1wG zrz_!rehvTRQ!L==HWS~b=MfbzTkp6oOd<~9ItCJE_e#kY8(uwnr|8s&+HLn(26I*Q zK$-xq;apRWC>^CV(vX<3y+G4~!9(nwTAH^X)`{@13sIhCY1Nj@20OTOHUg+ri5F)6CC?&M`OVx+RN`#!HZL@mBHmfCuf^d6Zwh%Ihasi>&40J1Bj?BEu+S_D5Ny2+WPRqA5=5ITsQ#94RI|wOOI(g-{QKes z6?g`EN-sC>q*}f9ddEwb$og>s2{DxUTy{L(wLWOd)X0ak4Qbm!8Q$Y$m!78gv3d~! zI67HlNKYl|D!uPJ_{#Dve15L$rPdo;_n-x(@}Oh!MV+6&#zr2_Jmpf8jJrF7L7E4R zAqGPCjhE}$0hclZ8(pUI1;*v)DrUY&zJPgpGX#9sswz`GITKIvF>m}*T5xn`tqLlp0WZ>~)E{h-XB%?w!R&~^1I#4uvEY2Rfw&%7WZi??+_rZ(wQZiy?mmOCP0ysP}MfV71)psy!5M8_UT~^Fs^}BWS3`}8hPVTofN}TM}?40Z3Rr=D5D5BUe*5M3E8B+} z^z`pwKtX8l<+o==q!U=C4A4oZ$WxV&{7ZP2ZIsLwrN9`WpmY8`EE+fPDY{l!)xV zLHW^z{whTjKY;!fpT&Pb`euZ0ZS~8j{R~I~ngM|2@4vF>N7TMcsQxO3bVDyjc zThWsEN36dZZQbF+L8NGe$O|lHh!=uD_dy@}@95ud**?i2{J(m$--_;!b5Z0Cbq#*Z ze8G|HZ^K`AfRKtnMeb+h2vAe-cgP|Z|I%c9>S${5x5!_1-0Ji}s2!kJ@iTHVXxH-Z zkbii|%IezL|81NN*(5eVaefOzfA}pMzF*lsq9CK}zeD~u{QqTy_4YNFr9p!65}<1R z>cbt&%cv~rEA$!EYO_X5wv^zZ8hV^mF+_WYTf<| zvVTlgC=ABoS5Qs`fJ(}@ec~Tiwof?zZ!vvS#uqX%)HnaT_W@};2Nw>?xMYwyJns*9 z&^_B{29%Y*k(Qq`?CvZ#@WOiPrvDTR)L}AX|1o0!!IkaPO!Iq0|I&DqH`KQ_wla15 zyY!&lTeQ{zy_X^q2nenp9RErW4QL7FH`4Q`ck=g%0Y4)52T``qqQI|Ney-Pl&j5a$ z-W>y`#IG5CuHS#p0Df509Rse+uNnUG=qB*@4Sr0iHfaI=Ct2G_LTVE{KW08at<_Rk$YbI$ML|Mg}NI1~7m$sLn%?tjVj*I5O=bbUu4 zQ1Ckh;0xJ*PQYKS_TJ%Jf+i8ap4t4>Y~<&)UvM_?Wz;)1-=hDO4Ya8GXPUoS(7U5~ qUh;p5=C78P?r8YR{#Tm2g(g`^7|@vi+fE!S#4*S<1hxFzxBml(1y>UQ literal 0 HcmV?d00001 diff --git a/spirit/lib/spirit-core-lexer-1.9.98.jar b/spirit/lib/spirit-core-lexer-1.9.98.jar deleted file mode 100644 index 51b006fdff2c7b8d08bead503e4be1a785f87d85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21917 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 DC+@9@ diff --git a/spirit/lib/spirit-core-lexer-2.0.48.jar b/spirit/lib/spirit-core-lexer-2.0.48.jar new file mode 100644 index 0000000000000000000000000000000000000000..07f245ab0e8abc7b0e4acebdccd6ffd6d701aa9c GIT binary patch literal 22166 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 MvT!pn)Odq<00YQO&j0`b literal 0 HcmV?d00001 diff --git a/spirit/lib/spirit-output-java-1.9.98.jar b/spirit/lib/spirit-output-java-1.9.98.jar deleted file mode 100644 index 6fb65a7c0c17b95d50361df991410ac79ab58b58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33578 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 MUFvAve*X4<0FV2ro&W#< literal 0 HcmV?d00001 diff --git a/spirit/lib/spirit-starter-java-1.9.98.jar b/spirit/lib/spirit-starter-java-1.9.98.jar deleted file mode 100644 index 033e6373c89871491c566cc876c2338afa0972ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6412 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 diff --git a/spirit/lib/spirit-starter-java-2.0.48.jar b/spirit/lib/spirit-starter-java-2.0.48.jar new file mode 100644 index 0000000000000000000000000000000000000000..5c00ea9e9332fbd188f1e914f5d53e6f480cd834 GIT binary patch literal 6480 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 Sa0Jl+a&ZSk+QBa&fd2#kwPJ$+ literal 0 HcmV?d00001 diff --git a/spirit/lib_web/spirit-starter-kit-1.9.98.jar b/spirit/lib_web/spirit-starter-kit-1.9.98.jar deleted file mode 100644 index c8385f77a99fc93c868de139ed8bfa3dd84a5479..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16524 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 Xagf&pkymxY>z~7GJ>BWfbZ6%Ki}l{S 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 as#aPI^fiVA008~<&;E7hCj7oc2KawIOJ~Ob literal 0 HcmV?d00001 diff --git a/spirit/src/com.sum.test/Main.sp b/spirit/src/com.sum.spirit.example/Main.sp similarity index 100% rename from spirit/src/com.sum.test/Main.sp rename to spirit/src/com.sum.spirit.example/Main.sp diff --git a/spirit/target/.keep b/spirit/target/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/spirit/target/com/sum/spirit/lib/Maps.java b/spirit/target/com/sum/spirit/lib/Maps.java new file mode 100644 index 00000000..14eda487 --- /dev/null +++ b/spirit/target/com/sum/spirit/lib/Maps.java @@ -0,0 +1,79 @@ +package com.sum.spirit.lib; + +import java.util.HashMap; +import java.util.Map; + +public class Maps { + + public static HashMap newHashMap() { + return new HashMap<>(); + } + + public static Map of() { + return newHashMap(); + } + + public static Map of(K k1, V v1) { + Map map = of(); + map.put(k1, v1); + return map; + } + + public static Map of(K k1, V v1, K k2, V v2) { + Map map = of(); + map.put(k1, v1); + map.put(k2, v2); + return map; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3) { + Map map = of(); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + return map; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { + Map map = of(); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + return map; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { + Map map = of(); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + return map; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) { + Map map = of(); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + map.put(k6, v6); + return map; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) { + Map map = of(); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + map.put(k6, v6); + map.put(k7, v7); + return map; + } + +} -- Gitee From c6d034447062c37b37f85414bfa4f0e58ca69d45 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 9 Apr 2021 15:40:31 +0800 Subject: [PATCH 043/121] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E6=8E=A8=E5=AF=BC=E6=97=B6=E6=8A=A5=E7=A9=BA=E6=8C=87=E9=92=88?= =?UTF-8?q?=E7=9A=84=E6=83=85=E5=86=B5=EF=BC=8C=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=A1=88=E4=BE=8B=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=AF=B9json=E7=BB=93=E6=9E=84=E4=BD=93=E7=9A=84=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/common/enums/SyntaxEnum.java | 1 + .../core/compile/deduce/TypeDerivator.java | 2 +- .../linker/AbstractAdaptiveLinker.java | 7 +++- .../core/element/DocumentReaderImpl.java | 36 +++++++++++++++---- .../core/element/action/SyntaxRecognizer.java | 6 +++- .../spirit/core/element/frame/Syntactic.java | 4 +++ .../src/test/java/com/sum/test/type/Type.java | 3 ++ .../test/resources/com.sum.test/type/Type.sp | 9 +++++ 8 files changed, 59 insertions(+), 9 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java index 92c63fdf..3cc2e359 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java @@ -22,6 +22,7 @@ public enum SyntaxEnum { DECLARE_FUNC, // String call() { FUNC, // func call() { FIELD_ASSIGN, // horse.name = "Jessie" + OBJECT_ASSIGN, // horse = { INVOKE, // horse.call() RETURN, // return "I am Jessie!" IF, // if name == "Jessie" { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java index d0b191bd..69b2b60f 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java @@ -88,7 +88,7 @@ public class TypeDerivator { if (token != null) { return factory.create(clazz, token); } - return StaticTypes.OBJECT;// 如果不存在继承,则默认是继承Object + return null; } public List getInterfaceTypes(IClass clazz) { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java index 3815ff1b..f565f892 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java @@ -48,9 +48,14 @@ public abstract class AbstractAdaptiveLinker implements ClassLinker, Initializin if (type.isArray()) { return StaticTypes.OBJECT; } + // 如果不存在父类,则返回Object IType superType = getLinker(type).getSuperType(type); if (superType == null) { - return null; + if (!StaticTypes.OBJECT.equals(type)) { + return StaticTypes.OBJECT; + } else { + return null; + } } int modifiers = type.getModifiers(); if (modifiers == ModifierEnum.THIS.value || modifiers == ModifierEnum.SUPER.value) { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DocumentReaderImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DocumentReaderImpl.java index 9ef2985b..ed6c7d86 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DocumentReaderImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DocumentReaderImpl.java @@ -10,6 +10,8 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.constants.Constants; import com.sum.spirit.common.utils.ConfigUtils; +import com.sum.spirit.common.utils.LineUtils; +import com.sum.spirit.common.utils.Lists; import com.sum.spirit.core.api.DocumentReader; import com.sum.spirit.core.api.ElementBuilder; import com.sum.spirit.core.element.entity.Document; @@ -18,6 +20,7 @@ import com.sum.spirit.core.element.entity.Line; import com.sum.spirit.core.element.entity.Statement; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.StrUtil; @Component public class DocumentReaderImpl implements DocumentReader { @@ -39,19 +42,24 @@ public class DocumentReaderImpl implements DocumentReader { public void doReadLines(Document document, List lines) { Stack> stack = new Stack<>(); stack.push(document); - for (int number = 0; number < lines.size(); number++) { - String text = lines.get(number); - Line line = new Line(number + 1, text); + for (int index = 0; index < lines.size(); index++) { + String text = lines.get(index); + Line line = new Line(index + 1, text); if (line.isIgnore()) { continue; } Element element = builder.build(line); + // what like "var = {" + if (mergeLinesIfPossible(document, lines, index, element)) { + index--; + continue; + } // what like "if xxx : xxx : xxx" List sublines = splitLine(element); if (sublines != null && !sublines.isEmpty()) { - lines.remove(number); - lines.addAll(number, sublines); - number--; + lines.remove(index); + lines.addAll(index, sublines); + index--; } else { if (line.isEnding()) { @@ -65,6 +73,22 @@ public class DocumentReaderImpl implements DocumentReader { } } + public boolean mergeLinesIfPossible(Document document, List lines, int startIndex, Element element) { + if (element.isObjectAssign()) { + StringBuilder builder = new StringBuilder(lines.get(startIndex)); + for (int index = startIndex + 1; index < lines.size(); index++) { + builder.append(StrUtil.removeAny(lines.get(index), "\t").trim()); + int end = LineUtils.findEndIndex(builder, 0, '{', '}'); + if (end != -1) { + Lists.remove(lines, startIndex, index + 1); + lines.add(startIndex, builder.toString()); + return true; + } + } + } + return false; + } + public List splitLine(Element element) { if (element.isIf() || element.isFor() || element.isForIn() || element.isWhile()) { if (!element.contains(":")) { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java index a14c9048..b9d88a15 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java @@ -145,7 +145,11 @@ public class SyntaxRecognizer { } else if (firstToken.isAssign()) { Token prevToken = firstNode.prev.token; - if (prevToken.isType()) {// String text = "abc" + Token nextToken = firstNode.next.token; + if (nextToken.isSeparator() && SymbolEnum.LEFT_CURLY_BRACKET.value.equals(nextToken.toString())) {// var = { + return SyntaxEnum.OBJECT_ASSIGN; + + } else if (prevToken.isType()) {// String text = "abc" return SyntaxEnum.DECLARE_ASSIGN; } else if (prevToken.isVariable()) {// text = "abc" diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java index 6ab1c2fd..d094e8c0 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java @@ -55,6 +55,10 @@ public abstract class Syntactic extends Statement { return syntax == SyntaxEnum.ASSIGN; } + public boolean isObjectAssign() { + return syntax == SyntaxEnum.OBJECT_ASSIGN; + } + public boolean isDeclareFunc() { return syntax == SyntaxEnum.DECLARE_FUNC; } diff --git a/spirit-test/src/test/java/com/sum/test/type/Type.java b/spirit-test/src/test/java/com/sum/test/type/Type.java index 02570515..b39c71d1 100644 --- a/spirit-test/src/test/java/com/sum/test/type/Type.java +++ b/spirit-test/src/test/java/com/sum/test/type/Type.java @@ -104,6 +104,9 @@ public class Type { logger.info(strxxxx); boolean bbxxx = getArray()[0]; logger.info("" + bbxxx); + Map objvar = Maps.of("name", "chen", "age", 18, "from", "China", "brother", Lists.newArrayList("wanhao", "chenzhe")); + String str0 = objvar.toString(); + logger.info(str0); } public String testParam(@Deprecated String str, Object obj) { diff --git a/spirit-test/src/test/resources/com.sum.test/type/Type.sp b/spirit-test/src/test/resources/com.sum.test/type/Type.sp index c788a565..8917d7f9 100644 --- a/spirit-test/src/test/resources/com.sum.test/type/Type.sp +++ b/spirit-test/src/test/resources/com.sum.test/type/Type.sp @@ -129,6 +129,15 @@ class Type { bbxxx=getArray()[0] print "" + bbxxx + + objvar = { + "name" : "chen", + "age" : 18, + "from" : "China", + "brother" : ["wanhao", "chenzhe"] + } + str0 = objvar.toString() + print str0 } func testParam(@Deprecated String str, Object obj){ -- Gitee From b7729940a515f507f02f34063ab5f901005bf465 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 9 Apr 2021 15:52:33 +0800 Subject: [PATCH 044/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/compile/linker/AbstractAdaptiveLinker.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java index f565f892..40a3d9a0 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java @@ -48,14 +48,13 @@ public abstract class AbstractAdaptiveLinker implements ClassLinker, Initializin if (type.isArray()) { return StaticTypes.OBJECT; } + if (StaticTypes.OBJECT.equals(type)) { + return null; + } // 如果不存在父类,则返回Object IType superType = getLinker(type).getSuperType(type); if (superType == null) { - if (!StaticTypes.OBJECT.equals(type)) { - return StaticTypes.OBJECT; - } else { - return null; - } + return StaticTypes.OBJECT; } int modifiers = type.getModifiers(); if (modifiers == ModifierEnum.THIS.value || modifiers == ModifierEnum.SUPER.value) { -- Gitee From 9db5d24df65779a1cc8724a8ccda2065bea1c060 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 9 Apr 2021 16:07:48 +0800 Subject: [PATCH 045/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/api/TypeFactory.java | 13 +++++++++ .../sum/spirit/core/clazz/entity/IClass.java | 29 ++++++++++++++++--- .../sum/spirit/core/compile/ClassVisiter.java | 6 ++-- .../compile/action/ElementTypeDeclarer.java | 4 +-- .../compile/deduce/AbstractTypeFactory.java | 8 ++--- .../compile/deduce/InvocationVisiter.java | 2 +- .../core/compile/deduce/TypeDerivator.java | 24 +-------------- ...{TypeFactory.java => TypeFactoryImpl.java} | 2 +- .../core/compile/deduce/VariableTracker.java | 4 +-- .../core/compile/linker/AdaptiveLinker.java | 4 +-- .../core/compile/linker/CodeLinker.java | 8 ++--- .../output/java/deduce/NativeFactory.java | 4 +-- 12 files changed, 58 insertions(+), 50 deletions(-) create mode 100644 spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/TypeFactory.java rename spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/{TypeFactory.java => TypeFactoryImpl.java} (98%) diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/TypeFactory.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/TypeFactory.java new file mode 100644 index 00000000..6027dd98 --- /dev/null +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/TypeFactory.java @@ -0,0 +1,13 @@ +package com.sum.spirit.core.api; + +import com.sum.spirit.core.clazz.entity.IClass; +import com.sum.spirit.core.clazz.entity.IType; +import com.sum.spirit.core.element.entity.Token; + +public interface TypeFactory { + + IType create(String className); + + IType create(IClass clazz, Token token); + +} diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java index aa014d48..be7e5138 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java @@ -1,10 +1,13 @@ package com.sum.spirit.core.clazz.entity; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.SpringUtils; +import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.frame.ImportUnit; import com.sum.spirit.core.clazz.utils.TypeUtils; import com.sum.spirit.core.element.entity.Element; @@ -45,6 +48,14 @@ public class IClass extends ImportUnit { return token; } + public String getSimpleName() { + return TypeUtils.getTargetName(getTypeToken().toString()); + } + + public String getClassName() { + return packageStr + "." + getSimpleName(); + } + public int getTypeVariableIndex(String genericName) { String simpleName = getTypeToken().toString(); // 这样分割,是有风险的,不过一般来说,类型说明里面不会再有嵌套 @@ -60,12 +71,22 @@ public class IClass extends ImportUnit { return -1; } - public String getSimpleName() { - return TypeUtils.getTargetName(getTypeToken().toString()); + public IType getSuperType() {// 注意:这里返回的是Super + Token token = element.getKeywordParam(KeywordEnum.EXTENDS.value);// 这里返回的,可以是泛型格式,而不是className + if (token != null) { + TypeFactory factory = SpringUtils.getBean(TypeFactory.class); + return factory.create(this, token); + } + return null; } - public String getClassName() { - return packageStr + "." + getSimpleName(); + public List getInterfaceTypes() { + List interfaces = new ArrayList<>(); + TypeFactory factory = SpringUtils.getBean(TypeFactory.class); + for (Token token : element.getKeywordParams(KeywordEnum.IMPLS.value)) { + interfaces.add(factory.create(this, token)); + } + return interfaces; } public IField getField(String fieldName) { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java index eea8b765..f6aa9a8c 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java @@ -20,7 +20,7 @@ import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.entity.IVariable; import com.sum.spirit.core.clazz.frame.MemberUnit; import com.sum.spirit.core.compile.deduce.TypeDerivator; -import com.sum.spirit.core.compile.deduce.TypeFactory; +import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; import com.sum.spirit.core.compile.entity.MethodContext; import com.sum.spirit.core.compile.entity.StaticTypes; import com.sum.spirit.core.element.entity.Element; @@ -33,7 +33,7 @@ import cn.hutool.core.lang.Assert; public class ClassVisiter { @Autowired - public TypeFactory factory; + public TypeFactoryImpl factory; @Autowired public ElementBuilder builder; @Autowired @@ -62,7 +62,7 @@ public class ClassVisiter { } public void visitAnnotations(IClass clazz, List annotations) { - TypeFactory factory = SpringUtils.getBean(TypeFactory.class); + TypeFactoryImpl factory = SpringUtils.getBean(TypeFactoryImpl.class); annotations.forEach(annotation -> annotation.setType(factory.create(clazz, annotation.token))); } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java index 0c09be3b..b9aebdaf 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java @@ -6,7 +6,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.core.clazz.entity.IClass; -import com.sum.spirit.core.compile.deduce.TypeFactory; +import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Token; @@ -16,7 +16,7 @@ import com.sum.spirit.core.element.entity.Token; public class ElementTypeDeclarer extends AbstractElementAction { @Autowired - public TypeFactory factory; + public TypeFactoryImpl factory; @Override public void handle(ElementEvent event) { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/AbstractTypeFactory.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/AbstractTypeFactory.java index 3c771657..437d31d1 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/AbstractTypeFactory.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/AbstractTypeFactory.java @@ -7,14 +7,14 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import com.sum.spirit.core.api.SemanticParser; +import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.entity.StaticTypes; -import com.sum.spirit.core.element.entity.Token; import cn.hutool.core.lang.Assert; -public abstract class AbstractTypeFactory { +public abstract class AbstractTypeFactory implements TypeFactory { @Autowired public SemanticParser parser; @@ -40,8 +40,4 @@ public abstract class AbstractTypeFactory { return create(clazz, parser.getToken(text)); } - public abstract IType create(String className); - - public abstract IType create(IClass clazz, Token token); - } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java index 17fe190a..2917729a 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java @@ -22,7 +22,7 @@ public class InvocationVisiter { @Autowired public ClassLinker linker; @Autowired - public TypeFactory factory; + public TypeFactoryImpl factory; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java index 69b2b60f..b6a16f7a 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java @@ -1,21 +1,15 @@ package com.sum.spirit.core.compile.deduce; -import java.util.ArrayList; -import java.util.List; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; -import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.enums.ModifierEnum; import com.sum.spirit.core.api.ClassLinker; -import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.TypeBuilder; import com.sum.spirit.core.clazz.utils.TypeVisiter; import com.sum.spirit.core.compile.entity.StaticTypes; -import com.sum.spirit.core.element.entity.Token; import cn.hutool.core.lang.Assert; @@ -24,7 +18,7 @@ import cn.hutool.core.lang.Assert; public class TypeDerivator { @Autowired - public TypeFactory factory; + public TypeFactoryImpl factory; @Autowired public ClassLinker linker; @@ -83,20 +77,4 @@ public class TypeDerivator { return false; } - public IType getSuperType(IClass clazz) {// 注意:这里返回的是Super - Token token = clazz.element.getKeywordParam(KeywordEnum.EXTENDS.value);// 这里返回的,可以是泛型格式,而不是className - if (token != null) { - return factory.create(clazz, token); - } - return null; - } - - public List getInterfaceTypes(IClass clazz) { - List interfaces = new ArrayList<>(); - for (Token token : clazz.element.getKeywordParams(KeywordEnum.IMPLS.value)) { - interfaces.add(factory.create(clazz, token)); - } - return interfaces; - } - } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactory.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java similarity index 98% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactory.java rename to spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java index 8bb5a7ee..0ca0b084 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactory.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java @@ -22,7 +22,7 @@ import cn.hutool.core.lang.Assert; @Component @Primary -public class TypeFactory extends AbstractTypeFactory { +public class TypeFactoryImpl extends AbstractTypeFactory { @Autowired public AppClassLoader classLoader; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java index 08ffc59b..f425e08e 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java @@ -25,7 +25,7 @@ public class VariableTracker { @Autowired public ClassLinker linker; @Autowired - public TypeFactory factory; + public TypeFactoryImpl factory; @Autowired public TypeDerivator derivator; @@ -51,7 +51,7 @@ public class VariableTracker { public IType findTypeByKeyword(IClass clazz, String variableName) { if (KeywordEnum.isSuper(variableName)) {// super - return derivator.withSuperModifiers(derivator.getSuperType(clazz)); + return derivator.withSuperModifiers(clazz.getSuperType()); } else if (KeywordEnum.isThis(variableName)) {// this return derivator.withThisModifiers(clazz.getType()); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java index 65bc2182..e4371544 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java @@ -10,7 +10,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.deduce.TypeDerivator; -import com.sum.spirit.core.compile.deduce.TypeFactory; +import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; import com.sum.spirit.core.compile.entity.StaticTypes; import cn.hutool.core.lang.Assert; @@ -23,7 +23,7 @@ public class AdaptiveLinker extends AbstractAdaptiveLinker { public static final String ARRAY_LENGTH = "length"; @Autowired - public TypeFactory factory; + public TypeFactoryImpl factory; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/CodeLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/CodeLinker.java index 1d5a3a2f..ea9e3bb2 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/CodeLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/CodeLinker.java @@ -17,7 +17,7 @@ import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.AppClassLoader; import com.sum.spirit.core.compile.ClassVisiter; import com.sum.spirit.core.compile.deduce.TypeDerivator; -import com.sum.spirit.core.compile.deduce.TypeFactory; +import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; import cn.hutool.core.lang.Assert; @@ -28,7 +28,7 @@ public class CodeLinker implements ClassLinker { @Autowired public AppClassLoader classLoader; @Autowired - public TypeFactory factory; + public TypeFactoryImpl factory; @Autowired public ClassVisiter visiter; @Autowired @@ -55,14 +55,14 @@ public class CodeLinker implements ClassLinker { @Override public IType getSuperType(IType type) { IClass clazz = toClass(type); - return derivator.populate(type, derivator.getSuperType(clazz)); + return derivator.populate(type, clazz.getSuperType()); } @Override public List getInterfaceTypes(IType type) { IClass clazz = toClass(type); List interfaceTypes = new ArrayList<>(); - for (IType interfaceType : derivator.getInterfaceTypes(clazz)) { + for (IType interfaceType : clazz.getInterfaceTypes()) { interfaceTypes.add(derivator.populate(type, interfaceType)); } return interfaceTypes; diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java index a2277de9..1c1f5757 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java @@ -11,11 +11,11 @@ import java.util.List; import org.springframework.stereotype.Component; import com.sum.spirit.core.clazz.entity.IType; -import com.sum.spirit.core.compile.deduce.TypeFactory; +import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; import com.sum.spirit.core.compile.entity.StaticTypes; @Component -public class NativeFactory extends TypeFactory { +public class NativeFactory extends TypeFactoryImpl { public IType create(Class clazz) { IType type = create(clazz.getName()); -- Gitee From f0620dcb27a8da96f815ea66d50debfab8f52d77 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 9 Apr 2021 16:52:11 +0800 Subject: [PATCH 046/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/core/api/ImportSelector.java | 0 .../sum/spirit/core/api/StaticTypesCtor.java | 0 .../spirit/core/clazz/frame/ImportUnit.java | 88 +++++++++++++++++ .../spirit/core/clazz/utils}/StaticTypes.java | 2 +- .../sum/spirit/core/compile/AutoImporter.java | 9 +- .../sum/spirit/core/compile/ClassVisiter.java | 2 +- .../compile/deduce/AbstractTypeFactory.java | 2 +- .../core/compile/deduce/ImportManager.java | 99 ------------------- .../core/compile/deduce/SimpleDeducer.java | 2 +- .../core/compile/deduce/TypeDerivator.java | 2 +- .../core/compile/deduce/TypeFactoryImpl.java | 8 +- .../linker/AbstractAdaptiveLinker.java | 2 +- .../core/compile/linker/AdaptiveLinker.java | 2 +- .../output/java/action/CommonAction.java | 9 +- .../output/java/action/StatementAction.java | 7 +- .../java/action/StringEqualsAction.java | 9 +- .../output/java/action/StringLogicAction.java | 11 +-- .../output/java/deduce/NativeFactory.java | 2 +- 18 files changed, 111 insertions(+), 145 deletions(-) rename spirit-core/{spirit-core-compile => spirit-core-class}/src/main/java/com/sum/spirit/core/api/ImportSelector.java (100%) rename spirit-core/{spirit-core-compile => spirit-core-class}/src/main/java/com/sum/spirit/core/api/StaticTypesCtor.java (100%) rename spirit-core/{spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity => spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils}/StaticTypes.java (99%) delete mode 100644 spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/ImportManager.java diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ImportSelector.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ImportSelector.java similarity index 100% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ImportSelector.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ImportSelector.java diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/StaticTypesCtor.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/StaticTypesCtor.java similarity index 100% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/StaticTypesCtor.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/StaticTypesCtor.java diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportUnit.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportUnit.java index 3fd21ba8..4393b7dd 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportUnit.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportUnit.java @@ -4,15 +4,32 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; +import com.sum.spirit.common.enums.PrimitiveEnum; import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.SpringUtils; +import com.sum.spirit.core.api.ImportSelector; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.clazz.entity.Import; +import com.sum.spirit.core.clazz.utils.TypeUtils; import com.sum.spirit.core.element.entity.Element; +import cn.hutool.core.lang.Assert; + public abstract class ImportUnit extends AnnotationUnit { + public static List importSelectors; + public List imports; + public static List getImportSelectors() { + synchronized (ImportUnit.class) { + if (importSelectors == null) { + importSelectors = SpringUtils.getBeansAndSort(ImportSelector.class); + } + return importSelectors; + } + } + public ImportUnit(List imports, List annotations, Element element) { super(annotations, element); this.imports = imports != null ? new ArrayList<>(imports) : new ArrayList<>(); @@ -34,4 +51,75 @@ public abstract class ImportUnit extends AnnotationUnit { return Lists.findOne(imports, import0 -> import0.matchSimpleName(simpleName)); } + public String findClassName(String simpleName) { + // 校验 + Assert.notContain(simpleName, ".", "Simple name cannot contains \".\""); + + // 如果传进来是个数组,那么处理一下 + String targetName = TypeUtils.getTargetName(simpleName); + boolean isArray = TypeUtils.isArray(simpleName); + + // 1.如果是基本类型,基本类型数组 + String className = PrimitiveEnum.tryGetClassName(simpleName); + + // 2.首先先去引入里面找 + if (className == null) { + Import import0 = findImportByLastName(targetName); + className = import0 != null ? import0.getClassName() : null; + className = className != null ? TypeUtils.getClassName(isArray, className) : null; + } + + // 3.使用类加载器,进行查询 + if (className == null) { + className = findClassNameByLoader(targetName); + className = className != null ? TypeUtils.getClassName(isArray, className) : null; + } + + Assert.notNull(className, "No import info found!simpleName:[" + simpleName + "]"); + return className; + } + + public boolean addImport(String className) { + // 如果是数组,则把修饰符号去掉 + String targetName = TypeUtils.getTargetName(className); + String lastName = TypeUtils.getLastName(className); + + // 1. 原始类型不添加 + if (PrimitiveEnum.isPrimitive(targetName)) { + return true; + } + + // 2.如果引入了,则不必引入了 + Import import0 = findImport(targetName); + if (import0 != null) { + return !import0.hasAlias() ? true : false; + } + + // 3.如果存在简称相同的,则也不能引入 + Import import1 = findImportByLastName(lastName); + if (import1 != null) { + return false; + } + + // 4.基础类型或拓展类型不添加 + if (!shouldImport(getClassName(), targetName)) { + return true; + } + + imports.add(new Import(targetName)); + return true; + } + + public String findClassNameByLoader(String simpleName) { + return Lists.collectOne(getImportSelectors(), importSelector -> importSelector.findClassName(simpleName)); + } + + public boolean shouldImport(String selfName, String className) { + Boolean flag = Lists.collectOne(getImportSelectors(), importSelector -> importSelector.isHandle(className), + importSelector -> importSelector.shouldImport(selfName, className)); + return flag == null ? true : flag; + } + + public abstract String getClassName(); + } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity/StaticTypes.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils/StaticTypes.java similarity index 99% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity/StaticTypes.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils/StaticTypes.java index da0fbd0a..a958cfd0 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity/StaticTypes.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils/StaticTypes.java @@ -1,4 +1,4 @@ -package com.sum.spirit.core.compile.entity; +package com.sum.spirit.core.clazz.utils; import java.util.Map; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AutoImporter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AutoImporter.java index 131ddd63..d4ef1a99 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AutoImporter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AutoImporter.java @@ -16,7 +16,6 @@ import com.sum.spirit.core.api.SemanticParser; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.TypeVisiter; -import com.sum.spirit.core.compile.deduce.ImportManager; import com.sum.spirit.core.element.entity.Element; @Component @@ -29,12 +28,10 @@ public class AutoImporter { public ElementBuilder builder; @Autowired public SemanticParser parser; - @Autowired - public ImportManager manager; public void autoImport(IClass clazz) { Set classNames = dependencies(clazz); - classNames.forEach(className -> manager.addImport(clazz, className)); + classNames.forEach(className -> clazz.addImport(className)); } /** @@ -66,7 +63,7 @@ public class AutoImporter { while (matcher.find() && matcher.groupCount() > 0) { String targetName = matcher.group(matcher.groupCount() - 1); if (parser.isType(targetName)) { - String className = manager.findClassName(clazz, targetName); + String className = clazz.findClassName(targetName); classNames.add(className); } } @@ -79,7 +76,7 @@ public class AutoImporter { public String getFinalName(IClass clazz, IType type) { return TypeVisiter.visitName(type, eachType -> { - if (!manager.addImport(clazz, eachType.getClassName())) { + if (!clazz.addImport(eachType.getClassName())) { return eachType.getTypeName(); } return eachType.toString(); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java index f6aa9a8c..f78f5c04 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java @@ -19,10 +19,10 @@ import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.entity.IVariable; import com.sum.spirit.core.clazz.frame.MemberUnit; +import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.compile.deduce.TypeDerivator; import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; import com.sum.spirit.core.compile.entity.MethodContext; -import com.sum.spirit.core.compile.entity.StaticTypes; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/AbstractTypeFactory.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/AbstractTypeFactory.java index 437d31d1..b7b28fbc 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/AbstractTypeFactory.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/AbstractTypeFactory.java @@ -10,7 +10,7 @@ import com.sum.spirit.core.api.SemanticParser; import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; -import com.sum.spirit.core.compile.entity.StaticTypes; +import com.sum.spirit.core.clazz.utils.StaticTypes; import cn.hutool.core.lang.Assert; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/ImportManager.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/ImportManager.java deleted file mode 100644 index ee40436d..00000000 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/ImportManager.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.sum.spirit.core.compile.deduce; - -import java.util.List; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.annotation.DependsOn; -import org.springframework.stereotype.Component; - -import com.sum.spirit.common.enums.PrimitiveEnum; -import com.sum.spirit.common.utils.Lists; -import com.sum.spirit.common.utils.SpringUtils; -import com.sum.spirit.core.api.ImportSelector; -import com.sum.spirit.core.clazz.entity.IClass; -import com.sum.spirit.core.clazz.entity.Import; -import com.sum.spirit.core.clazz.utils.TypeUtils; - -import cn.hutool.core.lang.Assert; - -@Component -@DependsOn("springUtils") -public class ImportManager implements InitializingBean { - - public List importSelectors; - - @Override - public void afterPropertiesSet() throws Exception { - importSelectors = SpringUtils.getBeansAndSort(ImportSelector.class); - } - - public String findClassName(IClass clazz, String simpleName) { - // 校验 - Assert.notContain(simpleName, ".", "Simple name cannot contains \".\""); - - // 如果传进来是个数组,那么处理一下 - String targetName = TypeUtils.getTargetName(simpleName); - boolean isArray = TypeUtils.isArray(simpleName); - - // 1.如果是基本类型,基本类型数组 - String className = PrimitiveEnum.tryGetClassName(simpleName); - - // 2.首先先去引入里面找 - if (className == null) { - Import import0 = clazz.findImportByLastName(targetName); - className = import0 != null ? import0.getClassName() : null; - className = className != null ? TypeUtils.getClassName(isArray, className) : null; - } - - // 3.使用类加载器,进行查询 - if (className == null) { - className = findClassName(targetName); - className = className != null ? TypeUtils.getClassName(isArray, className) : null; - } - - Assert.notNull(className, "No import info found!simpleName:[" + simpleName + "]"); - return className; - } - - public boolean addImport(IClass clazz, String className) { - // 如果是数组,则把修饰符号去掉 - String targetName = TypeUtils.getTargetName(className); - String lastName = TypeUtils.getLastName(className); - - // 1. 原始类型不添加 - if (PrimitiveEnum.isPrimitive(targetName)) { - return true; - } - - // 2.如果引入了,则不必引入了 - Import import0 = clazz.findImport(targetName); - if (import0 != null) { - return !import0.hasAlias() ? true : false; - } - - // 3.如果存在简称相同的,则也不能引入 - Import import1 = clazz.findImportByLastName(lastName); - if (import1 != null) { - return false; - } - - // 4.基础类型或拓展类型不添加 - if (!shouldImport(clazz.getClassName(), targetName)) { - return true; - } - - clazz.imports.add(new Import(targetName)); - return true; - } - - public String findClassName(String simpleName) { - return Lists.collectOne(importSelectors, importSelector -> importSelector.findClassName(simpleName)); - } - - public boolean shouldImport(String selfName, String className) { - Boolean flag = Lists.collectOne(importSelectors, importSelector -> importSelector.isHandle(className), - importSelector -> importSelector.shouldImport(selfName, className)); - return flag == null ? true : flag; - } - -} diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleDeducer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleDeducer.java index 35650164..ad21c0fd 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleDeducer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleDeducer.java @@ -7,7 +7,7 @@ import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.core.api.TreeBuilder; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; -import com.sum.spirit.core.compile.entity.StaticTypes; +import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.element.entity.Node; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java index b6a16f7a..af3aa1cb 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java @@ -7,9 +7,9 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.ModifierEnum; import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.clazz.entity.IType; +import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.clazz.utils.TypeBuilder; import com.sum.spirit.core.clazz.utils.TypeVisiter; -import com.sum.spirit.core.compile.entity.StaticTypes; import cn.hutool.core.lang.Assert; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java index 0ca0b084..7ba42d65 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java @@ -12,9 +12,9 @@ import com.sum.spirit.common.enums.ModifierEnum; import com.sum.spirit.common.enums.PrimitiveEnum; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; +import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.clazz.utils.TypeUtils; import com.sum.spirit.core.compile.AppClassLoader; -import com.sum.spirit.core.compile.entity.StaticTypes; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @@ -29,8 +29,6 @@ public class TypeFactoryImpl extends AbstractTypeFactory { @Autowired public SimpleDeducer deducer; @Autowired - public ImportManager manager; - @Autowired public TypeDerivator derivator; @Override @@ -71,12 +69,12 @@ public class TypeFactoryImpl extends AbstractTypeFactory { if (clazz.getTypeVariableIndex(simpleName) >= 0) { return createTypeVariable(simpleName);// T or K } - return create(manager.findClassName(clazz, simpleName)); + return create(clazz.findClassName(simpleName)); } else if (token.value instanceof Statement) { Statement statement = token.getValue(); // List // Class String simpleName = statement.getStr(0); - IType type = create(manager.findClassName(clazz, simpleName)); + IType type = create(clazz.findClassName(simpleName)); type.setGenericTypes(getGenericTypes(clazz, statement)); return type; } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java index 40a3d9a0..08f0405a 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java @@ -10,7 +10,7 @@ import com.sum.spirit.common.utils.Lists; import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.clazz.entity.IType; -import com.sum.spirit.core.compile.entity.StaticTypes; +import com.sum.spirit.core.clazz.utils.StaticTypes; public abstract class AbstractAdaptiveLinker implements ClassLinker, InitializingBean { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java index e4371544..73333a56 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java @@ -9,9 +9,9 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.core.clazz.entity.IType; +import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.compile.deduce.TypeDerivator; import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; -import com.sum.spirit.core.compile.entity.StaticTypes; import cn.hutool.core.lang.Assert; diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java index 256b63b2..7808220f 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java @@ -1,6 +1,5 @@ package com.sum.spirit.output.java.action; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -8,7 +7,6 @@ import com.google.common.collect.Lists; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.compile.action.AbstractElementAction; -import com.sum.spirit.core.compile.deduce.ImportManager; import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @@ -19,9 +17,6 @@ import com.sum.spirit.lib.Maps; @Order(-100) public class CommonAction extends AbstractElementAction { - @Autowired - public ImportManager manager; - @Override public void handle(ElementEvent event) { IClass clazz = event.clazz; @@ -40,7 +35,7 @@ public class CommonAction extends AbstractElementAction { Statement subStatement = token.getValue(); subStatement.set(0, new Token(TokenTypeEnum.CUSTOM_PREFIX, "Lists.newArrayList(")); subStatement.set(subStatement.size() - 1, new Token(TokenTypeEnum.CUSTOM_SUFFIX, ")")); - manager.addImport(clazz, Lists.class.getName()); + clazz.addImport(Lists.class.getName()); } else if (token.isMap()) {// {"key":"value"} => Maps.of("key","value"); Statement subStatement = token.getValue(); @@ -51,7 +46,7 @@ public class CommonAction extends AbstractElementAction { } subStatement.set(0, new Token(TokenTypeEnum.CUSTOM_PREFIX, "Maps.of(")); subStatement.set(subStatement.size() - 1, new Token(TokenTypeEnum.CUSTOM_SUFFIX, ")")); - manager.addImport(clazz, Maps.class.getName()); + clazz.addImport(Maps.class.getName()); } }); }); diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java index f55466f2..c4b8e008 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java @@ -17,7 +17,6 @@ import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.AutoImporter; import com.sum.spirit.core.compile.action.AbstractElementAction; import com.sum.spirit.core.compile.deduce.SimpleDeducer; -import com.sum.spirit.core.compile.deduce.ImportManager; import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.element.ElementBuilderImpl; import com.sum.spirit.core.element.entity.Element; @@ -36,8 +35,6 @@ public class StatementAction extends AbstractElementAction { public SimpleDeducer deducer; @Autowired public AutoImporter importer; - @Autowired - public ImportManager manager; @Override public void handle(ElementEvent event) { @@ -99,8 +96,8 @@ public class StatementAction extends AbstractElementAction { element.add(new Token(TokenTypeEnum.CUSTOM_SUFFIX, ");")); if (clazz.getField("logger") == null) { - manager.addImport(clazz, Logger.class.getName()); - manager.addImport(clazz, LoggerFactory.class.getName()); + clazz.addImport(Logger.class.getName()); + clazz.addImport(LoggerFactory.class.getName()); Element loggerElement = builder.build("Logger logger = LoggerFactory.getLogger(" + clazz.getSimpleName() + ".class)"); loggerElement.addModifier(JavaBuilder.FINAL_KEYWORD); loggerElement.addModifier(KeywordEnum.STATIC.value); diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java index f2ac3551..663ab004 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java @@ -4,7 +4,6 @@ import java.util.HashMap; import java.util.Map; import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -12,8 +11,7 @@ import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; -import com.sum.spirit.core.compile.deduce.ImportManager; -import com.sum.spirit.core.compile.entity.StaticTypes; +import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; import com.sum.spirit.output.java.utils.TypeUtils; @@ -24,9 +22,6 @@ public class StringEqualsAction extends AbstractTreeElementAction { public static final String FORMAT = "StringUtils.equals(%s, %s)"; - @Autowired - public ImportManager manager; - @Override public boolean isTrigger(Token currentToken) { return currentToken.isEquals() || currentToken.isUnequals(); @@ -53,7 +48,7 @@ public class StringEqualsAction extends AbstractTreeElementAction { expressToken.setAttr(AttributeEnum.TYPE, StaticTypes.BOOLEAN); expressToken.setAttr(AttributeEnum.TREE_ID, currentToken.attr(AttributeEnum.TREE_ID)); statement.replaceTokens(start, end, expressToken); - manager.addImport(clazz, StringUtils.class.getName()); + clazz.addImport(StringUtils.class.getName()); } } diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java index 9a5be660..d38ea329 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java @@ -4,7 +4,6 @@ import java.util.HashMap; import java.util.Map; import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -12,8 +11,7 @@ import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; -import com.sum.spirit.core.compile.deduce.ImportManager; -import com.sum.spirit.core.compile.entity.StaticTypes; +import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; import com.sum.spirit.output.java.utils.TypeUtils; @@ -24,9 +22,6 @@ public class StringLogicAction extends AbstractTreeElementAction { public static final String FORMAT = "StringUtils.isNotEmpty(%s)"; - @Autowired - public ImportManager manager; - @Override public boolean isTrigger(Token currentToken) { return currentToken.isLogical() && (currentToken.isNegate() || currentToken.isLogicAnd() || currentToken.isLogicOr()); @@ -55,7 +50,7 @@ public class StringLogicAction extends AbstractTreeElementAction { expressToken.setAttr(AttributeEnum.TYPE, StaticTypes.BOOLEAN); expressToken.setAttr(AttributeEnum.TREE_ID, currentToken.attr(AttributeEnum.TREE_ID) + "-0"); statement.replaceTokens(start, index, expressToken); - manager.addImport(clazz, StringUtils.class.getName()); + clazz.addImport(StringUtils.class.getName()); } } @@ -70,7 +65,7 @@ public class StringLogicAction extends AbstractTreeElementAction { expressToken.setAttr(AttributeEnum.TYPE, StaticTypes.BOOLEAN); expressToken.setAttr(AttributeEnum.TREE_ID, currentToken.attr(AttributeEnum.TREE_ID) + "-1"); statement.replaceTokens(index + 1, end, expressToken); - manager.addImport(clazz, StringUtils.class.getName()); + clazz.addImport(StringUtils.class.getName()); } } diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java index 1c1f5757..6f2c1636 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java @@ -11,8 +11,8 @@ import java.util.List; import org.springframework.stereotype.Component; import com.sum.spirit.core.clazz.entity.IType; +import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; -import com.sum.spirit.core.compile.entity.StaticTypes; @Component public class NativeFactory extends TypeFactoryImpl { -- Gitee From 9a2037a2fc08117c6ed68953dec3671f802e8fef Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 13 Apr 2021 13:43:10 +0800 Subject: [PATCH 047/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/clazz/ClassResolverImpl.java | 14 +++++++++++++ .../sum/spirit/core/clazz/entity/IClass.java | 8 ++++--- .../spirit/core/clazz/frame/ImportUnit.java | 21 +++++++------------ 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java index 08fe2f9c..0c63ceef 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java @@ -11,6 +11,8 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.core.api.ClassResolver; import com.sum.spirit.core.api.ElementBuilder; +import com.sum.spirit.core.api.ImportSelector; +import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IField; @@ -25,6 +27,10 @@ public class ClassResolverImpl implements ClassResolver { @Autowired public ElementBuilder builder; + @Autowired + public TypeFactory factory; + @Autowired + public List importSelectors; @Override public Map resolve(String packageStr, Document document) { @@ -56,6 +62,8 @@ public class ClassResolverImpl implements ClassResolver { } else if (element.isInterface() || element.isAbstract()) { // 接口和抽象类,只允许出现一个主类 mainClass = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); + mainClass.setFactory(factory); + mainClass.setImportSelectors(importSelectors); annotations.clear(); mainClass.packageStr = packageStr; mainClass.fields = fields; @@ -70,6 +78,8 @@ public class ClassResolverImpl implements ClassResolver { if (document.fileName.equals(targetName)) { mainClass = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); + mainClass.setFactory(factory); + mainClass.setImportSelectors(importSelectors); annotations.clear(); mainClass.packageStr = packageStr; mainClass.fields = fields; @@ -79,6 +89,8 @@ public class ClassResolverImpl implements ClassResolver { } else { IClass clazz = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); + clazz.setFactory(factory); + clazz.setImportSelectors(importSelectors); annotations.clear(); clazz.packageStr = packageStr; clazz.fields = new ArrayList<>(); @@ -93,6 +105,8 @@ public class ClassResolverImpl implements ClassResolver { if (mainClass == null) { Element element = builder.build("class " + document.fileName + " {"); mainClass = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); + mainClass.setFactory(factory); + mainClass.setImportSelectors(importSelectors); annotations.clear(); mainClass.packageStr = packageStr; mainClass.fields = fields; diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java index be7e5138..dc1d17f7 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java @@ -6,7 +6,6 @@ import java.util.stream.Collectors; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.utils.Lists; -import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.frame.ImportUnit; import com.sum.spirit.core.clazz.utils.TypeUtils; @@ -20,11 +19,16 @@ public class IClass extends ImportUnit { public String packageStr; public List fields; public List methods; + public TypeFactory factory; public IClass(List imports, List annotations, Element element) { super(imports, annotations, element); } + public void setFactory(TypeFactory factory) { + this.factory = factory; + } + public boolean isInterface() { return element.isInterface(); } @@ -74,7 +78,6 @@ public class IClass extends ImportUnit { public IType getSuperType() {// 注意:这里返回的是Super Token token = element.getKeywordParam(KeywordEnum.EXTENDS.value);// 这里返回的,可以是泛型格式,而不是className if (token != null) { - TypeFactory factory = SpringUtils.getBean(TypeFactory.class); return factory.create(this, token); } return null; @@ -82,7 +85,6 @@ public class IClass extends ImportUnit { public List getInterfaceTypes() { List interfaces = new ArrayList<>(); - TypeFactory factory = SpringUtils.getBean(TypeFactory.class); for (Token token : element.getKeywordParams(KeywordEnum.IMPLS.value)) { interfaces.add(factory.create(this, token)); } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportUnit.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportUnit.java index 4393b7dd..3447ff7c 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportUnit.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportUnit.java @@ -6,7 +6,6 @@ import java.util.stream.Collectors; import com.sum.spirit.common.enums.PrimitiveEnum; import com.sum.spirit.common.utils.Lists; -import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.ImportSelector; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.clazz.entity.Import; @@ -17,24 +16,18 @@ import cn.hutool.core.lang.Assert; public abstract class ImportUnit extends AnnotationUnit { - public static List importSelectors; - public List imports; - - public static List getImportSelectors() { - synchronized (ImportUnit.class) { - if (importSelectors == null) { - importSelectors = SpringUtils.getBeansAndSort(ImportSelector.class); - } - return importSelectors; - } - } + public List importSelectors; public ImportUnit(List imports, List annotations, Element element) { super(annotations, element); this.imports = imports != null ? new ArrayList<>(imports) : new ArrayList<>(); } + public void setImportSelectors(List importSelectors) { + this.importSelectors = importSelectors; + } + public List getImports() { return imports.stream().filter(imp -> !imp.hasAlias()).collect(Collectors.toList()); } @@ -111,11 +104,11 @@ public abstract class ImportUnit extends AnnotationUnit { } public String findClassNameByLoader(String simpleName) { - return Lists.collectOne(getImportSelectors(), importSelector -> importSelector.findClassName(simpleName)); + return Lists.collectOne(importSelectors, importSelector -> importSelector.findClassName(simpleName)); } public boolean shouldImport(String selfName, String className) { - Boolean flag = Lists.collectOne(getImportSelectors(), importSelector -> importSelector.isHandle(className), + Boolean flag = Lists.collectOne(importSelectors, importSelector -> importSelector.isHandle(className), importSelector -> importSelector.shouldImport(selfName, className)); return flag == null ? true : flag; } -- Gitee From cfa6c6ecb43452ec9e876fcbce2f01da38b15af3 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 13 Apr 2021 13:53:14 +0800 Subject: [PATCH 048/121] =?UTF-8?q?=E9=87=8D=E6=96=B0=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E6=8A=BD=E8=B1=A1=E7=B1=BB=E7=9A=84=E5=8C=85=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/sum/spirit/core/api/ClassLoader.java | 0 .../java/com/sum/spirit/core/clazz}/AbstractClassLoader.java | 2 +- .../java/com/sum/spirit/core/clazz}/AbstractURLClassLoader.java | 2 +- .../main/java/com/sum/spirit/core/compile/AppClassLoader.java | 1 + .../main/java/com/sum/spirit/output/java/ExtClassLoader.java | 2 +- 5 files changed, 4 insertions(+), 3 deletions(-) rename spirit-core/{spirit-core-compile => spirit-core-class}/src/main/java/com/sum/spirit/core/api/ClassLoader.java (100%) rename spirit-core/{spirit-core-compile/src/main/java/com/sum/spirit/core/compile => spirit-core-class/src/main/java/com/sum/spirit/core/clazz}/AbstractClassLoader.java (95%) rename spirit-core/{spirit-core-compile/src/main/java/com/sum/spirit/core/compile => spirit-core-class/src/main/java/com/sum/spirit/core/clazz}/AbstractURLClassLoader.java (98%) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassLoader.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ClassLoader.java similarity index 100% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassLoader.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ClassLoader.java diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AbstractClassLoader.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractClassLoader.java similarity index 95% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AbstractClassLoader.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractClassLoader.java index d4801541..88605957 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AbstractClassLoader.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractClassLoader.java @@ -1,4 +1,4 @@ -package com.sum.spirit.core.compile; +package com.sum.spirit.core.clazz; import java.net.URL; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AbstractURLClassLoader.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractURLClassLoader.java similarity index 98% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AbstractURLClassLoader.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractURLClassLoader.java index 8f210d3a..be569a2d 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AbstractURLClassLoader.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractURLClassLoader.java @@ -1,4 +1,4 @@ -package com.sum.spirit.core.compile; +package com.sum.spirit.core.clazz; import java.io.File; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java index 3e2b7495..b0efb2e1 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java @@ -11,6 +11,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.utils.URLFileUtils; import com.sum.spirit.core.api.Compiler; +import com.sum.spirit.core.clazz.AbstractURLClassLoader; import com.sum.spirit.core.clazz.entity.IClass; @Component diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/ExtClassLoader.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/ExtClassLoader.java index 646f6f55..7b970bb2 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/ExtClassLoader.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/ExtClassLoader.java @@ -9,10 +9,10 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.core.api.StaticTypesCtor; +import com.sum.spirit.core.clazz.AbstractClassLoader; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.TypeBuilder; import com.sum.spirit.core.clazz.utils.TypeUtils; -import com.sum.spirit.core.compile.AbstractClassLoader; import com.sum.spirit.output.java.utils.ReflectUtils; @Component -- Gitee From f0da0068527613456f8d0d88771eeef2181e4239 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 13 Apr 2021 13:58:42 +0800 Subject: [PATCH 049/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/clazz}/AbstractTypeFactory.java | 2 +- .../com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) rename spirit-core/{spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce => spirit-core-class/src/main/java/com/sum/spirit/core/clazz}/AbstractTypeFactory.java (96%) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/AbstractTypeFactory.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractTypeFactory.java similarity index 96% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/AbstractTypeFactory.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractTypeFactory.java index b7b28fbc..b96fd833 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/AbstractTypeFactory.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractTypeFactory.java @@ -1,4 +1,4 @@ -package com.sum.spirit.core.compile.deduce; +package com.sum.spirit.core.clazz; import java.util.Arrays; import java.util.Collections; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java index 7ba42d65..eb233e2e 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java @@ -10,6 +10,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.ModifierEnum; import com.sum.spirit.common.enums.PrimitiveEnum; +import com.sum.spirit.core.clazz.AbstractTypeFactory; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.StaticTypes; -- Gitee From d55a094398149b8af10085331541327ef8e8dd4d Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 13 Apr 2021 14:01:26 +0800 Subject: [PATCH 050/121] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=B1=BB=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{deduce/TypeFactoryImpl.java => AppTypeFactory.java} | 7 ++++--- .../java/com/sum/spirit/core/compile/ClassVisiter.java | 5 ++--- .../spirit/core/compile/action/ElementTypeDeclarer.java | 4 ++-- .../sum/spirit/core/compile/deduce/InvocationVisiter.java | 3 ++- .../com/sum/spirit/core/compile/deduce/TypeDerivator.java | 3 ++- .../sum/spirit/core/compile/deduce/VariableTracker.java | 3 ++- .../com/sum/spirit/core/compile/linker/AdaptiveLinker.java | 4 ++-- .../linker/{CodeLinker.java => AppClassLinker.java} | 6 +++--- .../com/sum/spirit/output/java/deduce/NativeFactory.java | 4 ++-- 9 files changed, 21 insertions(+), 18 deletions(-) rename spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/{deduce/TypeFactoryImpl.java => AppTypeFactory.java} (96%) rename spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/{CodeLinker.java => AppClassLinker.java} (95%) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java similarity index 96% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java rename to spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java index eb233e2e..4d4fbf39 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeFactoryImpl.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java @@ -1,4 +1,4 @@ -package com.sum.spirit.core.compile.deduce; +package com.sum.spirit.core.compile; import java.util.ArrayList; import java.util.List; @@ -15,7 +15,8 @@ import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.clazz.utils.TypeUtils; -import com.sum.spirit.core.compile.AppClassLoader; +import com.sum.spirit.core.compile.deduce.SimpleDeducer; +import com.sum.spirit.core.compile.deduce.TypeDerivator; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @@ -23,7 +24,7 @@ import cn.hutool.core.lang.Assert; @Component @Primary -public class TypeFactoryImpl extends AbstractTypeFactory { +public class AppTypeFactory extends AbstractTypeFactory { @Autowired public AppClassLoader classLoader; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java index f78f5c04..ffee8aad 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java @@ -21,7 +21,6 @@ import com.sum.spirit.core.clazz.entity.IVariable; import com.sum.spirit.core.clazz.frame.MemberUnit; import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.compile.deduce.TypeDerivator; -import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; import com.sum.spirit.core.compile.entity.MethodContext; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Statement; @@ -33,7 +32,7 @@ import cn.hutool.core.lang.Assert; public class ClassVisiter { @Autowired - public TypeFactoryImpl factory; + public AppTypeFactory factory; @Autowired public ElementBuilder builder; @Autowired @@ -62,7 +61,7 @@ public class ClassVisiter { } public void visitAnnotations(IClass clazz, List annotations) { - TypeFactoryImpl factory = SpringUtils.getBean(TypeFactoryImpl.class); + AppTypeFactory factory = SpringUtils.getBean(AppTypeFactory.class); annotations.forEach(annotation -> annotation.setType(factory.create(clazz, annotation.token))); } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java index b9aebdaf..e1fe1e2c 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java @@ -6,7 +6,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.core.clazz.entity.IClass; -import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; +import com.sum.spirit.core.compile.AppTypeFactory; import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Token; @@ -16,7 +16,7 @@ import com.sum.spirit.core.element.entity.Token; public class ElementTypeDeclarer extends AbstractElementAction { @Autowired - public TypeFactoryImpl factory; + public AppTypeFactory factory; @Override public void handle(ElementEvent event) { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java index 2917729a..478cea6e 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java @@ -10,6 +10,7 @@ import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; +import com.sum.spirit.core.compile.AppTypeFactory; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; import com.sum.spirit.core.element.utils.StmtVisiter; @@ -22,7 +23,7 @@ public class InvocationVisiter { @Autowired public ClassLinker linker; @Autowired - public TypeFactoryImpl factory; + public AppTypeFactory factory; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java index af3aa1cb..3eaa3526 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java @@ -10,6 +10,7 @@ import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.clazz.utils.TypeBuilder; import com.sum.spirit.core.clazz.utils.TypeVisiter; +import com.sum.spirit.core.compile.AppTypeFactory; import cn.hutool.core.lang.Assert; @@ -18,7 +19,7 @@ import cn.hutool.core.lang.Assert; public class TypeDerivator { @Autowired - public TypeFactoryImpl factory; + public AppTypeFactory factory; @Autowired public ClassLinker linker; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java index f425e08e..c33ef11d 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java @@ -11,6 +11,7 @@ import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.entity.IVariable; import com.sum.spirit.core.compile.ClassVisiter; +import com.sum.spirit.core.compile.AppTypeFactory; import com.sum.spirit.core.compile.entity.MethodContext; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.utils.StmtVisiter; @@ -25,7 +26,7 @@ public class VariableTracker { @Autowired public ClassLinker linker; @Autowired - public TypeFactoryImpl factory; + public AppTypeFactory factory; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java index 73333a56..f5da7e1e 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java @@ -10,8 +10,8 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.StaticTypes; +import com.sum.spirit.core.compile.AppTypeFactory; import com.sum.spirit.core.compile.deduce.TypeDerivator; -import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; import cn.hutool.core.lang.Assert; @@ -23,7 +23,7 @@ public class AdaptiveLinker extends AbstractAdaptiveLinker { public static final String ARRAY_LENGTH = "length"; @Autowired - public TypeFactoryImpl factory; + public AppTypeFactory factory; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/CodeLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java similarity index 95% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/CodeLinker.java rename to spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java index ea9e3bb2..d1836f8c 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/CodeLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java @@ -16,19 +16,19 @@ import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.AppClassLoader; import com.sum.spirit.core.compile.ClassVisiter; +import com.sum.spirit.core.compile.AppTypeFactory; import com.sum.spirit.core.compile.deduce.TypeDerivator; -import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; import cn.hutool.core.lang.Assert; @Component @Order(-100) -public class CodeLinker implements ClassLinker { +public class AppClassLinker implements ClassLinker { @Autowired public AppClassLoader classLoader; @Autowired - public TypeFactoryImpl factory; + public AppTypeFactory factory; @Autowired public ClassVisiter visiter; @Autowired diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java index 6f2c1636..1ff49ada 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java @@ -12,10 +12,10 @@ import org.springframework.stereotype.Component; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.StaticTypes; -import com.sum.spirit.core.compile.deduce.TypeFactoryImpl; +import com.sum.spirit.core.compile.AppTypeFactory; @Component -public class NativeFactory extends TypeFactoryImpl { +public class NativeFactory extends AppTypeFactory { public IType create(Class clazz) { IType type = create(clazz.getName()); -- Gitee From 7a79b362c84758dc7a7f54ab689d30011ba85f84 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 13 Apr 2021 14:25:54 +0800 Subject: [PATCH 051/121] =?UTF-8?q?=E7=BB=9F=E4=B8=80=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/core/api/TypeFactory.java | 10 ++++++++++ .../com/sum/spirit/core/clazz/AbstractTypeFactory.java | 4 ++++ .../java/com/sum/spirit/core/compile/ClassVisiter.java | 5 ++--- .../core/compile/action/ElementTypeDeclarer.java | 4 ++-- .../spirit/core/compile/deduce/InvocationVisiter.java | 4 ++-- .../sum/spirit/core/compile/deduce/TypeDerivator.java | 4 ++-- .../spirit/core/compile/deduce/VariableTracker.java | 4 ++-- .../sum/spirit/core/compile/linker/AdaptiveLinker.java | 4 ++-- .../sum/spirit/core/compile/linker/AppClassLinker.java | 4 ++-- .../{NativeFactory.java => NativeTypeFactory.java} | 2 +- .../output/java/linker/AbstractNativeLinker.java | 4 ++-- 11 files changed, 31 insertions(+), 18 deletions(-) rename spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/{NativeFactory.java => NativeTypeFactory.java} (94%) diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/TypeFactory.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/TypeFactory.java index 6027dd98..85759843 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/TypeFactory.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/TypeFactory.java @@ -1,5 +1,7 @@ package com.sum.spirit.core.api; +import java.util.List; + import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.element.entity.Token; @@ -8,6 +10,14 @@ public interface TypeFactory { IType create(String className); + IType create(String className, IType... genericTypes); + + IType create(String className, List genericTypes); + + IType createTypeVariable(String genericName); + IType create(IClass clazz, Token token); + IType create(IClass clazz, String text); + } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractTypeFactory.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractTypeFactory.java index b96fd833..513527db 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractTypeFactory.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractTypeFactory.java @@ -19,22 +19,26 @@ public abstract class AbstractTypeFactory implements TypeFactory { @Autowired public SemanticParser parser; + @Override public IType create(String className, IType... genericTypes) { return create(className, Arrays.asList(genericTypes)); } + @Override public IType create(String className, List genericTypes) { IType type = create(className); type.setGenericTypes(Collections.unmodifiableList(genericTypes)); return type; } + @Override public IType createTypeVariable(String genericName) {// T or K IType type = create(StaticTypes.OBJECT.getClassName()); type.setGenericName(genericName); return type; } + @Override public IType create(IClass clazz, String text) { Assert.isTrue(!text.contains("."), "Text cannot contains \".\". Please use the another create method!"); return create(clazz, parser.getToken(text)); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java index ffee8aad..85fc59a0 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java @@ -8,9 +8,9 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.common.utils.Lists; import com.sum.spirit.common.utils.ObjectUtils; -import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.api.ElementBuilder; +import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IField; @@ -32,7 +32,7 @@ import cn.hutool.core.lang.Assert; public class ClassVisiter { @Autowired - public AppTypeFactory factory; + public TypeFactory factory; @Autowired public ElementBuilder builder; @Autowired @@ -61,7 +61,6 @@ public class ClassVisiter { } public void visitAnnotations(IClass clazz, List annotations) { - AppTypeFactory factory = SpringUtils.getBean(AppTypeFactory.class); annotations.forEach(annotation -> annotation.setType(factory.create(clazz, annotation.token))); } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java index e1fe1e2c..b15828bb 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java @@ -5,8 +5,8 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IClass; -import com.sum.spirit.core.compile.AppTypeFactory; import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Token; @@ -16,7 +16,7 @@ import com.sum.spirit.core.element.entity.Token; public class ElementTypeDeclarer extends AbstractElementAction { @Autowired - public AppTypeFactory factory; + public TypeFactory factory; @Override public void handle(ElementEvent event) { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java index 478cea6e..76d2c9c1 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java @@ -8,9 +8,9 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.core.api.ClassLinker; +import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; -import com.sum.spirit.core.compile.AppTypeFactory; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; import com.sum.spirit.core.element.utils.StmtVisiter; @@ -23,7 +23,7 @@ public class InvocationVisiter { @Autowired public ClassLinker linker; @Autowired - public AppTypeFactory factory; + public TypeFactory factory; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java index 3eaa3526..4c70c355 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java @@ -6,11 +6,11 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.ModifierEnum; import com.sum.spirit.core.api.ClassLinker; +import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.clazz.utils.TypeBuilder; import com.sum.spirit.core.clazz.utils.TypeVisiter; -import com.sum.spirit.core.compile.AppTypeFactory; import cn.hutool.core.lang.Assert; @@ -19,7 +19,7 @@ import cn.hutool.core.lang.Assert; public class TypeDerivator { @Autowired - public AppTypeFactory factory; + public TypeFactory factory; @Autowired public ClassLinker linker; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java index c33ef11d..88d2e9e1 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java @@ -6,12 +6,12 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.core.api.ClassLinker; +import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.entity.IVariable; import com.sum.spirit.core.compile.ClassVisiter; -import com.sum.spirit.core.compile.AppTypeFactory; import com.sum.spirit.core.compile.entity.MethodContext; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.utils.StmtVisiter; @@ -26,7 +26,7 @@ public class VariableTracker { @Autowired public ClassLinker linker; @Autowired - public AppTypeFactory factory; + public TypeFactory factory; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java index f5da7e1e..adb0ead4 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java @@ -8,9 +8,9 @@ import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.KeywordEnum; +import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.StaticTypes; -import com.sum.spirit.core.compile.AppTypeFactory; import com.sum.spirit.core.compile.deduce.TypeDerivator; import cn.hutool.core.lang.Assert; @@ -23,7 +23,7 @@ public class AdaptiveLinker extends AbstractAdaptiveLinker { public static final String ARRAY_LENGTH = "length"; @Autowired - public AppTypeFactory factory; + public TypeFactory factory; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java index d1836f8c..33bab00f 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java @@ -9,6 +9,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.utils.Lists; import com.sum.spirit.core.api.ClassLinker; +import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IField; import com.sum.spirit.core.clazz.entity.IMethod; @@ -16,7 +17,6 @@ import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.AppClassLoader; import com.sum.spirit.core.compile.ClassVisiter; -import com.sum.spirit.core.compile.AppTypeFactory; import com.sum.spirit.core.compile.deduce.TypeDerivator; import cn.hutool.core.lang.Assert; @@ -28,7 +28,7 @@ public class AppClassLinker implements ClassLinker { @Autowired public AppClassLoader classLoader; @Autowired - public AppTypeFactory factory; + public TypeFactory factory; @Autowired public ClassVisiter visiter; @Autowired diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeTypeFactory.java similarity index 94% rename from spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java rename to spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeTypeFactory.java index 1ff49ada..9cf8de68 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeFactory.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeTypeFactory.java @@ -15,7 +15,7 @@ import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.compile.AppTypeFactory; @Component -public class NativeFactory extends AppTypeFactory { +public class NativeTypeFactory extends AppTypeFactory { public IType create(Class clazz) { IType type = create(clazz.getName()); diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeLinker.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeLinker.java index dd66fb07..156ad106 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeLinker.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeLinker.java @@ -11,14 +11,14 @@ import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.output.java.ExtClassLoader; import com.sum.spirit.output.java.deduce.NativeDerivator; -import com.sum.spirit.output.java.deduce.NativeFactory; +import com.sum.spirit.output.java.deduce.NativeTypeFactory; public abstract class AbstractNativeLinker implements ClassLinker { @Autowired public ExtClassLoader classLoader; @Autowired - public NativeFactory factory; + public NativeTypeFactory factory; @Autowired public NativeDerivator derivator; -- Gitee From 693fe90155112e2019b1b7a47688d8be01802e12 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 13 Apr 2021 14:46:20 +0800 Subject: [PATCH 052/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/clazz/ClassResolverImpl.java | 20 +++++++++---------- .../spirit/core/clazz/entity/IAnnotation.java | 4 ++-- .../sum/spirit/core/clazz/entity/IClass.java | 8 ++------ .../sum/spirit/core/clazz/entity/IField.java | 4 ++-- .../sum/spirit/core/clazz/entity/IMethod.java | 4 ++-- .../spirit/core/clazz/entity/IParameter.java | 4 ++-- .../spirit/core/clazz/entity/IVariable.java | 4 ++-- .../sum/spirit/core/clazz/entity/Import.java | 4 ++-- ...otationUnit.java => AnnotationEntity.java} | 4 ++-- .../{ElementUnit.java => ElementEntity.java} | 4 ++-- .../{ImportUnit.java => ImportEntity.java} | 8 ++------ .../{MemberUnit.java => MemberEntity.java} | 4 ++-- .../{TokenUnit.java => TokenEntity.java} | 4 ++-- .../frame/{TypeUnit.java => TypeEntity.java} | 2 +- .../sum/spirit/core/compile/ClassVisiter.java | 4 ++-- 15 files changed, 37 insertions(+), 45 deletions(-) rename spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/{AnnotationUnit.java => AnnotationEntity.java} (84%) rename spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/{ElementUnit.java => ElementEntity.java} (60%) rename spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/{ImportUnit.java => ImportEntity.java} (92%) rename spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/{MemberUnit.java => MemberEntity.java} (72%) rename spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/{TokenUnit.java => TokenEntity.java} (85%) rename spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/{TypeUnit.java => TypeEntity.java} (85%) diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java index 0c63ceef..586543b5 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java @@ -25,12 +25,12 @@ import com.sum.spirit.core.element.entity.Element; @Component public class ClassResolverImpl implements ClassResolver { - @Autowired - public ElementBuilder builder; @Autowired public TypeFactory factory; @Autowired public List importSelectors; + @Autowired + public ElementBuilder builder; @Override public Map resolve(String packageStr, Document document) { @@ -62,8 +62,8 @@ public class ClassResolverImpl implements ClassResolver { } else if (element.isInterface() || element.isAbstract()) { // 接口和抽象类,只允许出现一个主类 mainClass = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); - mainClass.setFactory(factory); - mainClass.setImportSelectors(importSelectors); + mainClass.factory = factory; + mainClass.importSelectors = importSelectors; annotations.clear(); mainClass.packageStr = packageStr; mainClass.fields = fields; @@ -78,8 +78,8 @@ public class ClassResolverImpl implements ClassResolver { if (document.fileName.equals(targetName)) { mainClass = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); - mainClass.setFactory(factory); - mainClass.setImportSelectors(importSelectors); + mainClass.factory = factory; + mainClass.importSelectors = importSelectors; annotations.clear(); mainClass.packageStr = packageStr; mainClass.fields = fields; @@ -89,8 +89,8 @@ public class ClassResolverImpl implements ClassResolver { } else { IClass clazz = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); - clazz.setFactory(factory); - clazz.setImportSelectors(importSelectors); + clazz.factory = factory; + clazz.importSelectors = importSelectors; annotations.clear(); clazz.packageStr = packageStr; clazz.fields = new ArrayList<>(); @@ -105,8 +105,8 @@ public class ClassResolverImpl implements ClassResolver { if (mainClass == null) { Element element = builder.build("class " + document.fileName + " {"); mainClass = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); - mainClass.setFactory(factory); - mainClass.setImportSelectors(importSelectors); + mainClass.factory = factory; + mainClass.importSelectors = importSelectors; annotations.clear(); mainClass.packageStr = packageStr; mainClass.fields = fields; diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IAnnotation.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IAnnotation.java index de0593b4..23663826 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IAnnotation.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IAnnotation.java @@ -1,9 +1,9 @@ package com.sum.spirit.core.clazz.entity; -import com.sum.spirit.core.clazz.frame.TokenUnit; +import com.sum.spirit.core.clazz.frame.TokenEntity; import com.sum.spirit.core.element.entity.Token; -public class IAnnotation extends TokenUnit { +public class IAnnotation extends TokenEntity { public IAnnotation(Token token) { super(token); diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java index dc1d17f7..ba638d37 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java @@ -7,14 +7,14 @@ import java.util.stream.Collectors; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.utils.Lists; import com.sum.spirit.core.api.TypeFactory; -import com.sum.spirit.core.clazz.frame.ImportUnit; +import com.sum.spirit.core.clazz.frame.ImportEntity; import com.sum.spirit.core.clazz.utils.TypeUtils; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Token; import cn.hutool.core.lang.Assert; -public class IClass extends ImportUnit { +public class IClass extends ImportEntity { public String packageStr; public List fields; @@ -25,10 +25,6 @@ public class IClass extends ImportUnit { super(imports, annotations, element); } - public void setFactory(TypeFactory factory) { - this.factory = factory; - } - public boolean isInterface() { return element.isInterface(); } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IField.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IField.java index 93891bec..e627f6e3 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IField.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IField.java @@ -2,10 +2,10 @@ package com.sum.spirit.core.clazz.entity; import java.util.List; -import com.sum.spirit.core.clazz.frame.MemberUnit; +import com.sum.spirit.core.clazz.frame.MemberEntity; import com.sum.spirit.core.element.entity.Element; -public class IField extends MemberUnit { +public class IField extends MemberEntity { public IField(List annotations, Element element) { super(annotations, element); diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IMethod.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IMethod.java index 7b1b4f70..34f08262 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IMethod.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IMethod.java @@ -6,11 +6,11 @@ import java.util.List; import com.google.common.base.Joiner; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.TokenTypeEnum; -import com.sum.spirit.core.clazz.frame.MemberUnit; +import com.sum.spirit.core.clazz.frame.MemberEntity; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Token; -public class IMethod extends MemberUnit { +public class IMethod extends MemberEntity { public List parameters = new ArrayList<>(); diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IParameter.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IParameter.java index bfb82074..8c25dec5 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IParameter.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IParameter.java @@ -2,10 +2,10 @@ package com.sum.spirit.core.clazz.entity; import java.util.List; -import com.sum.spirit.core.clazz.frame.AnnotationUnit; +import com.sum.spirit.core.clazz.frame.AnnotationEntity; import com.sum.spirit.core.element.entity.Element; -public class IParameter extends AnnotationUnit { +public class IParameter extends AnnotationEntity { public IParameter(List annotations, Element element) { super(annotations, element); diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IVariable.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IVariable.java index 8cef413e..6353aa45 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IVariable.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IVariable.java @@ -1,9 +1,9 @@ package com.sum.spirit.core.clazz.entity; -import com.sum.spirit.core.clazz.frame.TokenUnit; +import com.sum.spirit.core.clazz.frame.TokenEntity; import com.sum.spirit.core.element.entity.Token; -public class IVariable extends TokenUnit { +public class IVariable extends TokenEntity { public String blockId; diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/Import.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/Import.java index 26f10f33..2b3a48c3 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/Import.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/Import.java @@ -2,11 +2,11 @@ package com.sum.spirit.core.clazz.entity; import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.ElementBuilder; -import com.sum.spirit.core.clazz.frame.ElementUnit; +import com.sum.spirit.core.clazz.frame.ElementEntity; import com.sum.spirit.core.clazz.utils.TypeUtils; import com.sum.spirit.core.element.entity.Element; -public class Import extends ElementUnit { +public class Import extends ElementEntity { public Import(Element element) { super(element); diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/AnnotationUnit.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/AnnotationEntity.java similarity index 84% rename from spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/AnnotationUnit.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/AnnotationEntity.java index 8b9dfc10..c5b216d9 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/AnnotationUnit.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/AnnotationEntity.java @@ -7,11 +7,11 @@ import com.sum.spirit.common.utils.Lists; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.element.entity.Element; -public abstract class AnnotationUnit extends ElementUnit { +public abstract class AnnotationEntity extends ElementEntity { public List annotations; - public AnnotationUnit(List annotations, Element element) { + public AnnotationEntity(List annotations, Element element) { super(element); this.annotations = annotations != null ? new ArrayList<>(annotations) : new ArrayList<>(); } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ElementUnit.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ElementEntity.java similarity index 60% rename from spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ElementUnit.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ElementEntity.java index e860530e..d8198f82 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ElementUnit.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ElementEntity.java @@ -2,11 +2,11 @@ package com.sum.spirit.core.clazz.frame; import com.sum.spirit.core.element.entity.Element; -public abstract class ElementUnit extends TypeUnit { +public abstract class ElementEntity extends TypeEntity { public Element element; - public ElementUnit(Element element) { + public ElementEntity(Element element) { this.element = element; } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportUnit.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java similarity index 92% rename from spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportUnit.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java index 3447ff7c..c748cd98 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportUnit.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java @@ -14,20 +14,16 @@ import com.sum.spirit.core.element.entity.Element; import cn.hutool.core.lang.Assert; -public abstract class ImportUnit extends AnnotationUnit { +public abstract class ImportEntity extends AnnotationEntity { public List imports; public List importSelectors; - public ImportUnit(List imports, List annotations, Element element) { + public ImportEntity(List imports, List annotations, Element element) { super(annotations, element); this.imports = imports != null ? new ArrayList<>(imports) : new ArrayList<>(); } - public void setImportSelectors(List importSelectors) { - this.importSelectors = importSelectors; - } - public List getImports() { return imports.stream().filter(imp -> !imp.hasAlias()).collect(Collectors.toList()); } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/MemberUnit.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/MemberEntity.java similarity index 72% rename from spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/MemberUnit.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/MemberEntity.java index 0151b051..e5afa33e 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/MemberUnit.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/MemberEntity.java @@ -6,9 +6,9 @@ import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.element.entity.Element; -public abstract class MemberUnit extends AnnotationUnit { +public abstract class MemberEntity extends AnnotationEntity { - public MemberUnit(List annotations, Element element) { + public MemberEntity(List annotations, Element element) { super(annotations, element); } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TokenUnit.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TokenEntity.java similarity index 85% rename from spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TokenUnit.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TokenEntity.java index 3280fb73..38af5575 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TokenUnit.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TokenEntity.java @@ -3,11 +3,11 @@ package com.sum.spirit.core.clazz.frame; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.core.element.entity.Token; -public abstract class TokenUnit extends TypeUnit { +public abstract class TokenEntity extends TypeEntity { public Token token; - public TokenUnit(Token token) { + public TokenEntity(Token token) { this.token = token; } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TypeUnit.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TypeEntity.java similarity index 85% rename from spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TypeUnit.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TypeEntity.java index e8185b6b..23a0b3e4 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TypeUnit.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TypeEntity.java @@ -8,7 +8,7 @@ import lombok.Setter; @Getter @Setter -public abstract class TypeUnit { +public abstract class TypeEntity { @NonNull private IType type; } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java index 85fc59a0..7bccb4e3 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java @@ -18,7 +18,7 @@ import com.sum.spirit.core.clazz.entity.IMethod; import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.entity.IVariable; -import com.sum.spirit.core.clazz.frame.MemberUnit; +import com.sum.spirit.core.clazz.frame.MemberEntity; import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.compile.deduce.TypeDerivator; import com.sum.spirit.core.compile.entity.MethodContext; @@ -77,7 +77,7 @@ public class ClassVisiter { } } - public IType visitMember(IClass clazz, MemberUnit member) { + public IType visitMember(IClass clazz, MemberEntity member) { ObjectUtils.lock(member); // 防止循环依赖 IType type = member.getType(); if (type == null) { -- Gitee From 228b30212d60fb2b2c93a16c2bcc145a5c2c2c87 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 13 Apr 2021 14:52:59 +0800 Subject: [PATCH 053/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java index 586543b5..a9efdc12 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java @@ -38,9 +38,9 @@ public class ClassResolverImpl implements ClassResolver { Map classes = new LinkedHashMap<>(); List imports = new ArrayList<>(); List annotations = new ArrayList<>(); - IClass mainClass = null; List fields = new ArrayList<>(); List methods = new ArrayList<>(); + IClass mainClass = null; for (Element element : document) { if (element.isImport()) { -- Gitee From 37795b832d54f6ed8c1981efd6410a25cc36a04a Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 13 Apr 2021 15:42:22 +0800 Subject: [PATCH 054/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/common/enums/KeywordEnum.java | 4 +- .../spirit/core/clazz/ClassResolverImpl.java | 37 ++++++++----------- .../spirit/core/element/entity/Element.java | 6 ++- .../core/element/frame/KeywordTokenBox.java | 4 ++ .../output/java/action/StatementAction.java | 5 +-- 5 files changed, 27 insertions(+), 29 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/KeywordEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/KeywordEnum.java index 6ced4595..668b8775 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/KeywordEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/KeywordEnum.java @@ -37,10 +37,10 @@ public enum KeywordEnum { FINALLY("finally", KeywordTypeEnum.TOKEN), // INSTANCEOF("instanceof", KeywordTypeEnum.TOKEN), // - STATIC("static", KeywordTypeEnum.MODIFIER), // PUBLIC("public", KeywordTypeEnum.MODIFIER), // - PRIVATE("private", KeywordTypeEnum.MODIFIER), // PROTECTED("protected", KeywordTypeEnum.MODIFIER), // + PRIVATE("private", KeywordTypeEnum.MODIFIER), // + STATIC("static", KeywordTypeEnum.MODIFIER), // CONST("const", KeywordTypeEnum.MODIFIER), // VOLATILE("volatile", KeywordTypeEnum.MODIFIER), // SYNCH("synch", KeywordTypeEnum.MODIFIER); // diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java index a9efdc12..6f83909f 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java @@ -50,21 +50,18 @@ public class ClassResolverImpl implements ClassResolver { annotations.add(new IAnnotation(element.get(0))); } else if (element.isDeclare() || element.isDeclareAssign() || element.isAssign()) { - element.addModifier(KeywordEnum.STATIC.value).addModifier(KeywordEnum.PUBLIC.value); - fields.add(new IField(annotations, element)); - annotations.clear(); + element.addModifiers(KeywordEnum.PUBLIC.value, KeywordEnum.STATIC.value); + fields.add(new IField(copyAnnotations(annotations), element)); } else if (element.isDeclareFunc() || element.isFunc()) { - element.addModifier(KeywordEnum.STATIC.value).addModifier(KeywordEnum.PUBLIC.value); - methods.add(new IMethod(annotations, element)); - annotations.clear(); + element.addModifiers(KeywordEnum.PUBLIC.value, KeywordEnum.STATIC.value); + methods.add(new IMethod(copyAnnotations(annotations), element)); } else if (element.isInterface() || element.isAbstract()) { // 接口和抽象类,只允许出现一个主类 - mainClass = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); + mainClass = new IClass(imports, copyAnnotations(annotations), element.addModifiers(KeywordEnum.PUBLIC.value)); mainClass.factory = factory; mainClass.importSelectors = importSelectors; - annotations.clear(); mainClass.packageStr = packageStr; mainClass.fields = fields; mainClass.methods = methods; @@ -75,12 +72,10 @@ public class ClassResolverImpl implements ClassResolver { // 这里可能出现泛型,但是文件名一般是simpleName String simpleName = element.getKeywordParam(KeywordEnum.CLASS.value).toString(); String targetName = TypeUtils.getTargetName(simpleName); - if (document.fileName.equals(targetName)) { - mainClass = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); + mainClass = new IClass(imports, copyAnnotations(annotations), element.addModifiers(KeywordEnum.PUBLIC.value)); mainClass.factory = factory; mainClass.importSelectors = importSelectors; - annotations.clear(); mainClass.packageStr = packageStr; mainClass.fields = fields; mainClass.methods = methods; @@ -88,10 +83,9 @@ public class ClassResolverImpl implements ClassResolver { classes.put(mainClass.getClassName(), mainClass); } else { - IClass clazz = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); + IClass clazz = new IClass(imports, copyAnnotations(annotations), element.addModifiers(KeywordEnum.PUBLIC.value)); clazz.factory = factory; clazz.importSelectors = importSelectors; - annotations.clear(); clazz.packageStr = packageStr; clazz.fields = new ArrayList<>(); clazz.methods = new ArrayList<>(); @@ -104,10 +98,9 @@ public class ClassResolverImpl implements ClassResolver { // 如果不存在主类的声明,则虚拟一个Element if (mainClass == null) { Element element = builder.build("class " + document.fileName + " {"); - mainClass = new IClass(imports, annotations, element.addModifier(KeywordEnum.PUBLIC.value)); + mainClass = new IClass(imports, copyAnnotations(annotations), element.addModifiers(KeywordEnum.PUBLIC.value)); mainClass.factory = factory; mainClass.importSelectors = importSelectors; - annotations.clear(); mainClass.packageStr = packageStr; mainClass.fields = fields; mainClass.methods = methods; @@ -117,21 +110,23 @@ public class ClassResolverImpl implements ClassResolver { return classes; } - public void readRootElement(IClass clazz) { + public List copyAnnotations(List annotations) { + List newAnnotations = new ArrayList<>(annotations); + annotations.clear(); + return newAnnotations; + } + public void readRootElement(IClass clazz) { List annotations = new ArrayList<>(); - for (Element element : clazz.element.children) { if (element.isAnnotation()) { annotations.add(new IAnnotation(element.get(0))); } else if (element.isDeclare() || element.isDeclareAssign() || element.isAssign()) { - clazz.fields.add(new IField(annotations, element.addModifier(KeywordEnum.PUBLIC.value))); - annotations.clear(); + clazz.fields.add(new IField(copyAnnotations(annotations), element.addModifiers(KeywordEnum.PUBLIC.value))); } else if (element.isDeclareFunc() || element.isFunc()) { - clazz.methods.add(new IMethod(annotations, element.addModifier(KeywordEnum.PUBLIC.value))); - annotations.clear(); + clazz.methods.add(new IMethod(copyAnnotations(annotations), element.addModifiers(KeywordEnum.PUBLIC.value))); } } } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Element.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Element.java index 32d196b7..7f8856ec 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Element.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Element.java @@ -33,8 +33,10 @@ public class Element extends Syntactic { return modifiers.containsKeyword(keyword); } - public Element addModifier(String keyword) { - modifiers.addKeywordAtFirst(keyword); + public Element addModifiers(String... keywords) { + for (int i = keywords.length - 1; i >= 0; i--) { + modifiers.addKeywordAtFirst(keywords[i]); + } return this; } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/KeywordTokenBox.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/KeywordTokenBox.java index 2609a699..b83172fa 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/KeywordTokenBox.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/KeywordTokenBox.java @@ -41,6 +41,10 @@ public abstract class KeywordTokenBox extends TokenBox { add(0, new Token(TokenTypeEnum.KEYWORD, keyword)); } + public void addKeyword(String keyword) { + add(new Token(TokenTypeEnum.KEYWORD, keyword)); + } + public void insertKeywordAfter(String keyword, String newKeyword) { int index = indexOfKeyword(keyword); if (index != -1) { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java index c4b8e008..eca2977f 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java @@ -94,14 +94,11 @@ public class StatementAction extends AbstractElementAction { element.set(0, new Token(TokenTypeEnum.CUSTOM_PREFIX, "logger.error(")); } element.add(new Token(TokenTypeEnum.CUSTOM_SUFFIX, ");")); - if (clazz.getField("logger") == null) { clazz.addImport(Logger.class.getName()); clazz.addImport(LoggerFactory.class.getName()); Element loggerElement = builder.build("Logger logger = LoggerFactory.getLogger(" + clazz.getSimpleName() + ".class)"); - loggerElement.addModifier(JavaBuilder.FINAL_KEYWORD); - loggerElement.addModifier(KeywordEnum.STATIC.value); - loggerElement.addModifier(KeywordEnum.PUBLIC.value); + loggerElement.addModifiers(KeywordEnum.PUBLIC.value, KeywordEnum.STATIC.value, JavaBuilder.FINAL_KEYWORD); IField field = new IField(new ArrayList<>(), loggerElement); clazz.fields.add(0, field); } -- Gitee From bc5599d4c102ae21b9a81a38d058616aaccfb2d0 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 13 Apr 2021 15:55:13 +0800 Subject: [PATCH 055/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/clazz/ClassResolverImpl.java | 32 +++++++------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java index 6f83909f..5900cd60 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java @@ -60,11 +60,7 @@ public class ClassResolverImpl implements ClassResolver { } else if (element.isInterface() || element.isAbstract()) { // 接口和抽象类,只允许出现一个主类 mainClass = new IClass(imports, copyAnnotations(annotations), element.addModifiers(KeywordEnum.PUBLIC.value)); - mainClass.factory = factory; - mainClass.importSelectors = importSelectors; - mainClass.packageStr = packageStr; - mainClass.fields = fields; - mainClass.methods = methods; + initClass(mainClass, packageStr, fields, methods); readRootElement(mainClass); classes.put(mainClass.getClassName(), mainClass); @@ -74,21 +70,13 @@ public class ClassResolverImpl implements ClassResolver { String targetName = TypeUtils.getTargetName(simpleName); if (document.fileName.equals(targetName)) { mainClass = new IClass(imports, copyAnnotations(annotations), element.addModifiers(KeywordEnum.PUBLIC.value)); - mainClass.factory = factory; - mainClass.importSelectors = importSelectors; - mainClass.packageStr = packageStr; - mainClass.fields = fields; - mainClass.methods = methods; + initClass(mainClass, packageStr, fields, methods); readRootElement(mainClass); classes.put(mainClass.getClassName(), mainClass); } else { IClass clazz = new IClass(imports, copyAnnotations(annotations), element.addModifiers(KeywordEnum.PUBLIC.value)); - clazz.factory = factory; - clazz.importSelectors = importSelectors; - clazz.packageStr = packageStr; - clazz.fields = new ArrayList<>(); - clazz.methods = new ArrayList<>(); + initClass(clazz, packageStr, new ArrayList<>(), new ArrayList<>()); readRootElement(clazz); classes.put(clazz.getClassName(), clazz); } @@ -99,11 +87,7 @@ public class ClassResolverImpl implements ClassResolver { if (mainClass == null) { Element element = builder.build("class " + document.fileName + " {"); mainClass = new IClass(imports, copyAnnotations(annotations), element.addModifiers(KeywordEnum.PUBLIC.value)); - mainClass.factory = factory; - mainClass.importSelectors = importSelectors; - mainClass.packageStr = packageStr; - mainClass.fields = fields; - mainClass.methods = methods; + initClass(mainClass, packageStr, fields, methods); classes.put(mainClass.getClassName(), mainClass); } @@ -116,6 +100,14 @@ public class ClassResolverImpl implements ClassResolver { return newAnnotations; } + public void initClass(IClass clazz, String packageStr, List fields, List methods) { + clazz.packageStr = packageStr; + clazz.fields = fields; + clazz.methods = methods; + clazz.factory = factory; + clazz.importSelectors = importSelectors; + } + public void readRootElement(IClass clazz) { List annotations = new ArrayList<>(); for (Element element : clazz.element.children) { -- Gitee From f14d83442e43fc81942879423e90085243b4d121 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 13 Apr 2021 16:58:38 +0800 Subject: [PATCH 056/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/common/enums/AttributeEnum.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/AttributeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/AttributeEnum.java index d1fdf870..242d3dda 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/AttributeEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/AttributeEnum.java @@ -8,5 +8,6 @@ public enum AttributeEnum { TYPE, // 类型 DERIVED, // 是否声明 POSITION, // 在语句中的位置 - LENGTH; // 字符串的宽度 + LENGTH, // 字符串的宽度 + USER_DEFINED;// 用户自定义 } -- Gitee From 075fddc46c8aadf5afdca445b038a57e82b0cbd1 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 15 Apr 2021 09:38:08 +0800 Subject: [PATCH 057/121] =?UTF-8?q?=E4=BF=AE=E6=94=B9readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a1dfb75..e0ae7173 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ public class Main { 1. 下载安装sublime编辑器,并将项目中sublime-plugs目录下的所有文件,拷贝到sublime插件目录下的User文件夹中。 2. 下载项目中的spirit文件夹,到任意目录下。(spirit文件夹内为打包产物) 3. 在eclipse中,借助maven命令导出工程依赖项,并拷贝到spirit/lib_dep文件夹中。(Run As->Maven-build->dependency:copy-dependencies) -4. 双击运行spirit/bin/startup.bat,并在target目录下查看生成的示例代码。 +4. 双击运行spirit/bin/compile.bat,并在target目录下查看生成的示例代码。 ## Maven依赖 -- Gitee From d4859d53e7a27ee011577fb52c83fa19cc766381 Mon Sep 17 00:00:00 2001 From: chenT Date: Sun, 18 Apr 2021 18:01:10 +0800 Subject: [PATCH 058/121] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=B1=BB=E5=90=8D?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=BC=BA=E4=BB=A3=E7=A0=81=E5=8F=AF=E8=AF=BB?= =?UTF-8?q?=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/clazz/AbstractURLClassLoader.java | 15 ++++------- ...verImpl.java => DefaultClassResolver.java} | 10 ++++--- .../com/sum/spirit/core/api/ClassVisiter.java | 11 ++++++++ .../sum/spirit/core/api/ElementVisiter.java | 14 ++++++++++ .../spirit/core/compile/AppClassLoader.java | 1 + .../spirit/core/compile/AppTypeFactory.java | 4 +-- ...sVisiter.java => DefaultClassVisiter.java} | 9 ++++--- ...isiter.java => DefaultElementVisiter.java} | 10 ++++--- .../action/ElementExpressDeclarer.java | 8 +++--- .../compile/deduce/InvocationVisiter.java | 2 +- ...Deducer.java => SimpleSectionDeducer.java} | 2 +- .../core/compile/deduce/VariableTracker.java | 4 +-- .../core/compile/linker/AppClassLinker.java | 4 +-- ...erImpl.java => DefaultDocumentReader.java} | 27 +++++++++---------- ...erImpl.java => DefaultElementBuilder.java} | 2 +- ...erImpl.java => DefaultSemanticParser.java} | 2 +- ...ilderImpl.java => DefaultTreeBuilder.java} | 2 +- .../action/AbstractTreeElementAction.java | 4 +-- .../output/java/action/StatementAction.java | 8 +++--- .../com/sum/spirit/starter/JavaRunner.java | 22 +++++++-------- .../starter/kit/core/ElementSelector.java | 4 +-- 21 files changed, 95 insertions(+), 70 deletions(-) rename spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/{ClassResolverImpl.java => DefaultClassResolver.java} (97%) create mode 100644 spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassVisiter.java create mode 100644 spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementVisiter.java rename spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/{ClassVisiter.java => DefaultClassVisiter.java} (97%) rename spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/{ElementVisiter.java => DefaultElementVisiter.java} (90%) rename spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/{SimpleDeducer.java => SimpleSectionDeducer.java} (97%) rename spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/{DocumentReaderImpl.java => DefaultDocumentReader.java} (81%) rename spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/{ElementBuilderImpl.java => DefaultElementBuilder.java} (97%) rename spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/{SemanticParserImpl.java => DefaultSemanticParser.java} (98%) rename spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/{TreeBuilderImpl.java => DefaultTreeBuilder.java} (98%) diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractURLClassLoader.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractURLClassLoader.java index be569a2d..88d47171 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractURLClassLoader.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractURLClassLoader.java @@ -8,6 +8,7 @@ import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import org.apache.commons.io.FileUtils; @@ -18,31 +19,25 @@ import com.sum.spirit.common.utils.URLFileUtils; import com.sum.spirit.common.utils.Lists; import com.sum.spirit.core.clazz.entity.IClass; +import cn.hutool.core.lang.Assert; + public abstract class AbstractURLClassLoader extends AbstractClassLoader implements InitializingBean { public List urls = new ArrayList<>(); - public Map nameUrlMapping = new LinkedHashMap<>(); - public Map classes = new LinkedHashMap<>(); @Override public void afterPropertiesSet() throws Exception { - // 添加到urls String inputPath = ConfigUtils.getInputPath(); String extension = ConfigUtils.getFileExtension(); Collection files = FileUtils.listFiles(new File(inputPath), new String[] { extension }, true); files.forEach(file -> this.urls.add(URLFileUtils.toURL(file))); - // 添加到映射 File directory = new File(inputPath); - if (!directory.isDirectory()) { - throw new RuntimeException("The input path must be a directory!"); - } + Assert.isTrue(directory.isDirectory(), "The input path must be a directory!"); URL inputUrl = URLFileUtils.toURL(directory); urls.forEach(url -> { - // 去掉前缀 String name = url.toString().replace(inputUrl.toString(), "").replaceAll("/", "."); - // 去掉后缀 if (name.endsWith("." + extension)) { name = name.substring(0, name.lastIndexOf('.')); } @@ -82,7 +77,7 @@ public abstract class AbstractURLClassLoader extends AbstractClassLoader @Override public List getAllClasses() { - return classes.values().stream().filter(clazz -> clazz != null).collect(Collectors.toList()); + return classes.values().stream().filter(Objects::nonNull).collect(Collectors.toList()); } @Override diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java similarity index 97% rename from spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java index 5900cd60..ffca8ef3 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/ClassResolverImpl.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java @@ -23,24 +23,25 @@ import com.sum.spirit.core.element.entity.Document; import com.sum.spirit.core.element.entity.Element; @Component -public class ClassResolverImpl implements ClassResolver { +public class DefaultClassResolver implements ClassResolver { + @Autowired + public ElementBuilder builder; @Autowired public TypeFactory factory; @Autowired public List importSelectors; - @Autowired - public ElementBuilder builder; @Override public Map resolve(String packageStr, Document document) { Map classes = new LinkedHashMap<>(); + List imports = new ArrayList<>(); List annotations = new ArrayList<>(); + IClass mainClass = null; List fields = new ArrayList<>(); List methods = new ArrayList<>(); - IClass mainClass = null; for (Element element : document) { if (element.isImport()) { @@ -67,6 +68,7 @@ public class ClassResolverImpl implements ClassResolver { } else if (element.isClass()) { // 这里可能出现泛型,但是文件名一般是simpleName String simpleName = element.getKeywordParam(KeywordEnum.CLASS.value).toString(); + // 声明一个类型时,泛型参数不能多层嵌套 String targetName = TypeUtils.getTargetName(simpleName); if (document.fileName.equals(targetName)) { mainClass = new IClass(imports, copyAnnotations(annotations), element.addModifiers(KeywordEnum.PUBLIC.value)); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassVisiter.java new file mode 100644 index 00000000..0d546bf0 --- /dev/null +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassVisiter.java @@ -0,0 +1,11 @@ +package com.sum.spirit.core.api; + +import com.sum.spirit.core.clazz.entity.IClass; + +public interface ClassVisiter { + + void prepareForVisit(IClass clazz); + + void visitClass(IClass clazz); + +} diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementVisiter.java new file mode 100644 index 00000000..fe6c4595 --- /dev/null +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementVisiter.java @@ -0,0 +1,14 @@ +package com.sum.spirit.core.api; + +import com.sum.spirit.core.clazz.entity.IClass; +import com.sum.spirit.core.clazz.entity.IVariable; +import com.sum.spirit.core.compile.entity.MethodContext; +import com.sum.spirit.core.element.entity.Element; + +public interface ElementVisiter { + + IVariable visitElement(IClass clazz, Element element); + + IVariable visitElement(IClass clazz, Element element, MethodContext context); + +} diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java index b0efb2e1..02415f99 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppClassLoader.java @@ -10,6 +10,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.utils.URLFileUtils; +import com.sum.spirit.core.api.ClassVisiter; import com.sum.spirit.core.api.Compiler; import com.sum.spirit.core.clazz.AbstractURLClassLoader; import com.sum.spirit.core.clazz.entity.IClass; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java index 4d4fbf39..a493c584 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java @@ -15,7 +15,7 @@ import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.clazz.utils.TypeUtils; -import com.sum.spirit.core.compile.deduce.SimpleDeducer; +import com.sum.spirit.core.compile.deduce.SimpleSectionDeducer; import com.sum.spirit.core.compile.deduce.TypeDerivator; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @@ -29,7 +29,7 @@ public class AppTypeFactory extends AbstractTypeFactory { @Autowired public AppClassLoader classLoader; @Autowired - public SimpleDeducer deducer; + public SimpleSectionDeducer deducer; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java similarity index 97% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java rename to spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java index 7bccb4e3..323a3a87 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java @@ -8,8 +8,9 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.common.utils.Lists; import com.sum.spirit.common.utils.ObjectUtils; -import com.sum.spirit.core.api.ClassLinker; +import com.sum.spirit.core.api.ClassVisiter; import com.sum.spirit.core.api.ElementBuilder; +import com.sum.spirit.core.api.ElementVisiter; import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.clazz.entity.IClass; @@ -29,7 +30,7 @@ import com.sum.spirit.core.element.entity.Token; import cn.hutool.core.lang.Assert; @Component -public class ClassVisiter { +public class DefaultClassVisiter implements ClassVisiter { @Autowired public TypeFactory factory; @@ -38,10 +39,9 @@ public class ClassVisiter { @Autowired public ElementVisiter visiter; @Autowired - public ClassLinker linker; - @Autowired public TypeDerivator derivator; + @Override public void prepareForVisit(IClass clazz) { // 访问类型 clazz.setType(factory.create(clazz, clazz.getTypeToken())); @@ -49,6 +49,7 @@ public class ClassVisiter { clazz.methods.forEach(method -> visitParameters(clazz, method)); } + @Override public void visitClass(IClass clazz) { Assert.notNull(clazz.getType(), "Please invoke the method [prepareForVisit] first!"); // 访问注解 diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ElementVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java similarity index 90% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ElementVisiter.java rename to spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java index ad975d89..58ede9f1 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/ElementVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java @@ -11,9 +11,10 @@ import com.sum.spirit.common.constants.Constants; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.ElementAction; +import com.sum.spirit.core.api.ElementVisiter; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IVariable; -import com.sum.spirit.core.compile.deduce.SimpleDeducer; +import com.sum.spirit.core.compile.deduce.SimpleSectionDeducer; import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.compile.entity.MethodContext; import com.sum.spirit.core.element.entity.Element; @@ -22,11 +23,10 @@ import com.sum.spirit.core.element.entity.Token; @Component @DependsOn("springUtils") -public class ElementVisiter implements InitializingBean { +public class DefaultElementVisiter implements ElementVisiter, InitializingBean { @Autowired - public SimpleDeducer deducer; - + public SimpleSectionDeducer deducer; public List actions; @Override @@ -34,10 +34,12 @@ public class ElementVisiter implements InitializingBean { actions = SpringUtils.getBeansAndSort(ElementAction.class, Constants.SPIRIT_CORE_PACKAGE); } + @Override public IVariable visitElement(IClass clazz, Element element) { return visitElement(clazz, element, null); } + @Override public IVariable visitElement(IClass clazz, Element element, MethodContext context) { try { for (ElementAction action : actions) { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java index bd1c8a24..dd7c6824 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java @@ -9,8 +9,8 @@ import com.sum.spirit.core.api.ElementBuilder; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.entity.IVariable; -import com.sum.spirit.core.compile.ElementVisiter; -import com.sum.spirit.core.compile.deduce.SimpleDeducer; +import com.sum.spirit.core.compile.DefaultElementVisiter; +import com.sum.spirit.core.compile.deduce.SimpleSectionDeducer; import com.sum.spirit.core.compile.deduce.InvocationVisiter; import com.sum.spirit.core.compile.deduce.TypeDerivator; import com.sum.spirit.core.compile.deduce.VariableTracker; @@ -27,13 +27,13 @@ public class ElementExpressDeclarer extends AbstractElementAction { @Autowired public ElementBuilder builder; @Autowired - public ElementVisiter elementVisiter; + public DefaultElementVisiter elementVisiter; @Autowired public VariableTracker tracker; @Autowired public InvocationVisiter visiter; @Autowired - public SimpleDeducer deducer; + public SimpleSectionDeducer deducer; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java index 76d2c9c1..11eea308 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java @@ -19,7 +19,7 @@ import com.sum.spirit.core.element.utils.StmtVisiter; public class InvocationVisiter { @Autowired - public SimpleDeducer deducer; + public SimpleSectionDeducer deducer; @Autowired public ClassLinker linker; @Autowired diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleDeducer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleSectionDeducer.java similarity index 97% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleDeducer.java rename to spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleSectionDeducer.java index ad21c0fd..cfe7c198 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleDeducer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleSectionDeducer.java @@ -13,7 +13,7 @@ import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @Component -public class SimpleDeducer { +public class SimpleSectionDeducer { @Autowired public TreeBuilder builder; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java index 88d2e9e1..30ad1a18 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java @@ -11,7 +11,7 @@ import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.entity.IVariable; -import com.sum.spirit.core.compile.ClassVisiter; +import com.sum.spirit.core.compile.DefaultClassVisiter; import com.sum.spirit.core.compile.entity.MethodContext; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.utils.StmtVisiter; @@ -22,7 +22,7 @@ import cn.hutool.core.lang.Assert; public class VariableTracker { @Autowired - public ClassVisiter visiter; + public DefaultClassVisiter visiter; @Autowired public ClassLinker linker; @Autowired diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java index 33bab00f..f662d598 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java @@ -16,7 +16,7 @@ import com.sum.spirit.core.clazz.entity.IMethod; import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.AppClassLoader; -import com.sum.spirit.core.compile.ClassVisiter; +import com.sum.spirit.core.compile.DefaultClassVisiter; import com.sum.spirit.core.compile.deduce.TypeDerivator; import cn.hutool.core.lang.Assert; @@ -30,7 +30,7 @@ public class AppClassLinker implements ClassLinker { @Autowired public TypeFactory factory; @Autowired - public ClassVisiter visiter; + public DefaultClassVisiter visiter; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DocumentReaderImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java similarity index 81% rename from spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DocumentReaderImpl.java rename to spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java index ed6c7d86..71c27caa 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DocumentReaderImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java @@ -23,7 +23,7 @@ import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.StrUtil; @Component -public class DocumentReaderImpl implements DocumentReader { +public class DefaultDocumentReader implements DocumentReader { @Autowired public ElementBuilder builder; @@ -55,7 +55,7 @@ public class DocumentReaderImpl implements DocumentReader { continue; } // what like "if xxx : xxx : xxx" - List sublines = splitLine(element); + List sublines = splitLineIfPossible(element); if (sublines != null && !sublines.isEmpty()) { lines.remove(index); lines.addAll(index, sublines); @@ -89,20 +89,19 @@ public class DocumentReaderImpl implements DocumentReader { return false; } - public List splitLine(Element element) { + public List splitLineIfPossible(Element element) { if (element.isIf() || element.isFor() || element.isForIn() || element.isWhile()) { - if (!element.contains(":")) { - return null; - } - List subLines = new ArrayList<>(); - List statements = element.splitStmt(":"); - String indent = element.getIndent(); - subLines.add(indent + statements.get(0).toString() + " {"); - for (int i = 1; i < statements.size(); i++) { - subLines.add(indent + "\t" + statements.get(i).toString()); + if (element.contains(":")) { + String indent = element.getIndent(); + List subLines = new ArrayList<>(); + List statements = element.splitStmt(":"); + subLines.add(indent + statements.get(0).toString() + " {"); + for (int index = 1; index < statements.size(); index++) { + subLines.add(indent + "\t" + statements.get(index).toString()); + } + subLines.add(indent + "}"); + return subLines; } - subLines.add(indent + "}"); - return subLines; } return null; } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultElementBuilder.java similarity index 97% rename from spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java rename to spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultElementBuilder.java index 08c41db3..7c73c097 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/ElementBuilderImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultElementBuilder.java @@ -21,7 +21,7 @@ import com.sum.spirit.core.element.entity.Token; import cn.hutool.core.lang.Assert; @Component -public class ElementBuilderImpl implements ElementBuilder { +public class DefaultElementBuilder implements ElementBuilder { @Autowired public LineChecker checker; diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java similarity index 98% rename from spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java rename to spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java index fa87370f..253fc042 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SemanticParserImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java @@ -14,7 +14,7 @@ import com.sum.spirit.core.element.entity.Token; import cn.hutool.core.lang.Assert; @Component -public class SemanticParserImpl extends AbstractSemanticParser { +public class DefaultSemanticParser extends AbstractSemanticParser { @Autowired public Lexer lexer; diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/TreeBuilderImpl.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java similarity index 98% rename from spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/TreeBuilderImpl.java rename to spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java index 118e3dfb..9cc4b48d 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/TreeBuilderImpl.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java @@ -20,7 +20,7 @@ import com.sum.spirit.core.element.utils.PriorityNode; import com.sum.spirit.core.element.utils.PriorityNode.PriorityComparator; @Component -public class TreeBuilderImpl extends AbstractTreeBuilder { +public class DefaultTreeBuilder extends AbstractTreeBuilder { @Override public List buildNodes(List tokens) { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java index 393369a6..d06e8133 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java @@ -8,7 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.action.AbstractElementAction; -import com.sum.spirit.core.compile.deduce.SimpleDeducer; +import com.sum.spirit.core.compile.deduce.SimpleSectionDeducer; import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @@ -25,7 +25,7 @@ public abstract class AbstractTreeElementAction extends AbstractElementAction { public static final String NEXT_TYPE = "NEXT_TYPE"; @Autowired - public SimpleDeducer deducer; + public SimpleSectionDeducer deducer; @Override public void handle(ElementEvent event) { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java index eca2977f..4f28dd27 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java @@ -16,9 +16,9 @@ import com.sum.spirit.core.clazz.entity.IField; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.AutoImporter; import com.sum.spirit.core.compile.action.AbstractElementAction; -import com.sum.spirit.core.compile.deduce.SimpleDeducer; +import com.sum.spirit.core.compile.deduce.SimpleSectionDeducer; import com.sum.spirit.core.compile.entity.ElementEvent; -import com.sum.spirit.core.element.ElementBuilderImpl; +import com.sum.spirit.core.element.DefaultElementBuilder; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @@ -30,9 +30,9 @@ import com.sum.spirit.output.java.utils.TypeUtils; public class StatementAction extends AbstractElementAction { @Autowired - public ElementBuilderImpl builder; + public DefaultElementBuilder builder; @Autowired - public SimpleDeducer deducer; + public SimpleSectionDeducer deducer; @Autowired public AutoImporter importer; diff --git a/spirit-starter/spirit-starter-java/src/main/java/com/sum/spirit/starter/JavaRunner.java b/spirit-starter/spirit-starter-java/src/main/java/com/sum/spirit/starter/JavaRunner.java index 666a3276..ac187242 100644 --- a/spirit-starter/spirit-starter-java/src/main/java/com/sum/spirit/starter/JavaRunner.java +++ b/spirit-starter/spirit-starter-java/src/main/java/com/sum/spirit/starter/JavaRunner.java @@ -21,21 +21,21 @@ import com.sum.spirit.core.lexer.AliasCharsHandler; @Profile("compile") public class JavaRunner implements ApplicationRunner { + @Autowired + public RunningMonitor monitor; @Autowired public AppClassLoader loader; @Autowired public CodeBuilder builder; @Autowired - public AliasCharsHandler handler; - @Autowired - public RunningMonitor monitor; + public AliasCharsHandler aliasHandler; @Override public void run(ApplicationArguments args) throws Exception { monitor.printArgs(args); - long timestamp = System.currentTimeMillis(); + long startTime = System.currentTimeMillis(); compileAndGenerateFiles(); - monitor.printTotalTime(timestamp); + monitor.printTotalTime(startTime); } public void compileAndGenerateFiles() { @@ -43,20 +43,20 @@ public class JavaRunner implements ApplicationRunner { boolean debug = ConfigUtils.isDebug(); List classes = loader.getAllClasses(); classes.forEach(clazz -> { - String code = builder.build(clazz);// 输出目标代码 - code = replaceAlias(clazz, code); + String targetCode = builder.build(clazz); + targetCode = replaceAlias(clazz, targetCode); if (debug) { - System.out.println(code); + System.out.println(targetCode); } - if (StringUtils.isNotEmpty(outputPath)) {// 生成文件 - URLFileUtils.generateFile(outputPath, clazz.getClassName().replaceAll("\\.", "/") + ".java", code); + if (StringUtils.isNotEmpty(outputPath)) { + URLFileUtils.generateFile(outputPath, clazz.getClassName().replaceAll("\\.", "/") + ".java", targetCode); } }); } public String replaceAlias(IClass clazz, String code) { for (Import imp : clazz.getAliasImports()) { - code = handler.replace(code, imp.getAlias(), imp.getClassName()); + code = aliasHandler.replace(code, imp.getAlias(), imp.getClassName()); } return code; } diff --git a/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/ElementSelector.java b/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/ElementSelector.java index 5140b55a..d7a21742 100644 --- a/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/ElementSelector.java +++ b/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/ElementSelector.java @@ -10,14 +10,14 @@ import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.entity.IVariable; import com.sum.spirit.core.compile.CoreCompiler; -import com.sum.spirit.core.compile.ElementVisiter; +import com.sum.spirit.core.compile.DefaultElementVisiter; import com.sum.spirit.core.element.entity.Element; @Component public class ElementSelector extends CoreCompiler { @Autowired - public ElementVisiter visiter; + public DefaultElementVisiter visiter; public IType findElementAndGetType(IClass clazz, Integer lineNumber) { Element element = findElement(Arrays.asList(clazz.element), lineNumber); -- Gitee From cd42a9f73ae2586630b4fcfd9d18300222a9e442 Mon Sep 17 00:00:00 2001 From: chenT Date: Sun, 18 Apr 2021 18:19:39 +0800 Subject: [PATCH 059/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/sum/spirit/core/api/ElementVisiter.java | 2 +- .../java/com/sum/spirit/core/compile/DefaultClassVisiter.java | 2 +- .../com/sum/spirit/core/compile/DefaultElementVisiter.java | 4 ++-- .../spirit/core/compile/action/ElementExpressDeclarer.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementVisiter.java index fe6c4595..6f762d0c 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ElementVisiter.java @@ -9,6 +9,6 @@ public interface ElementVisiter { IVariable visitElement(IClass clazz, Element element); - IVariable visitElement(IClass clazz, Element element, MethodContext context); + IVariable visitElement(IClass clazz, MethodContext context, Element element); } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java index 323a3a87..5599208d 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java @@ -141,7 +141,7 @@ public class DefaultClassVisiter implements ClassVisiter { context.increaseDepth(); } // 对该元素进行分析 - IVariable variable = visiter.visitElement(clazz, element, context); + IVariable variable = visiter.visitElement(clazz, context, element); // 如果该元素不是return语句,并且变量不为空,则将变量添加到上下文中 if (!element.isReturn() && variable != null) { variable.blockId = context.getBlockId(); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java index 58ede9f1..98ee898a 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java @@ -36,11 +36,11 @@ public class DefaultElementVisiter implements ElementVisiter, InitializingBean { @Override public IVariable visitElement(IClass clazz, Element element) { - return visitElement(clazz, element, null); + return visitElement(clazz, null, element); } @Override - public IVariable visitElement(IClass clazz, Element element, MethodContext context) { + public IVariable visitElement(IClass clazz, MethodContext context, Element element) { try { for (ElementAction action : actions) { ElementEvent event = new ElementEvent(clazz, element, context); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java index dd7c6824..0019a126 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java @@ -82,7 +82,7 @@ public class ElementExpressDeclarer extends AbstractElementAction { Statement subStatement = statement.subStmt(1, statement.indexOf(";")); if (subStatement.size() > 0) { Element subElement = builder.rebuild(subStatement); - IVariable variable = elementVisiter.visitElement(clazz, subElement, context); + IVariable variable = elementVisiter.visitElement(clazz, context, subElement); if (variable != null) { variable.blockId = context.getBlockId(); context.variables.add(variable); -- Gitee From 94c9db08f0567eae57f5aa728717058c80076c08 Mon Sep 17 00:00:00 2001 From: chenT Date: Sun, 18 Apr 2021 19:22:38 +0800 Subject: [PATCH 060/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/common/utils/Splitter.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java index 9dbc6e9b..fd09ebbb 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java @@ -37,26 +37,26 @@ public class Splitter { public static List> splitByMatcherTrim(List list, Matcher matcher) { int[] indexs = CollUtil.indexOfAll(list, item -> matcher.accept(item)); - List> list0 = new ArrayList<>(); + List> subLists = new ArrayList<>(); int lastIndex = 0; - for (Integer index : indexs) { + for (int index : indexs) { if (index > lastIndex) { - list0.add(new ArrayList<>(list.subList(lastIndex, index))); + subLists.add(new ArrayList<>(list.subList(lastIndex, index))); } lastIndex = index + 1; } if (lastIndex != list.size()) { - list0.add(new ArrayList<>(list.subList(lastIndex, list.size()))); + subLists.add(new ArrayList<>(list.subList(lastIndex, list.size()))); } - return list0; + return subLists; } @SuppressWarnings("unchecked") public static List splitByMatcherTrim(List list, Matcher matcher, Factory> factory) { - List> items = splitByMatcherTrim(list, matcher); - List list0 = new ArrayList<>(); - items.forEach(item -> list0.add((V) factory.accept(item))); - return list0; + List> subLists = splitByMatcherTrim(list, matcher); + List anotherList = new ArrayList<>(); + subLists.forEach(subList -> anotherList.add((V) factory.accept(subList))); + return anotherList; } public static interface Matcher { -- Gitee From 7eda40d0d05a2431d782ff383b05f3281957510c Mon Sep 17 00:00:00 2001 From: chenT Date: Sun, 18 Apr 2021 19:24:33 +0800 Subject: [PATCH 061/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/compile/DefaultClassVisiter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java index 5599208d..24d7c49c 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java @@ -70,10 +70,10 @@ public class DefaultClassVisiter implements ClassVisiter { Token methodToken = method.element.findOneTokenOf(TokenTypeEnum.TYPE_INIT, TokenTypeEnum.LOCAL_METHOD); Statement statement = methodToken.getValue(); List statements = statement.subStmt("(", ")").splitStmt(","); - for (Statement paramStmt : statements) { - List annotations = Lists.filterStoppable(paramStmt, token -> token.isAnnotation(), token -> new IAnnotation(token)); - IParameter parameter = new IParameter(annotations, builder.rebuild(paramStmt)); - parameter.setType(factory.create(clazz, paramStmt.get(0))); + for (Statement parameterStmt : statements) { + List annotations = Lists.filterStoppable(parameterStmt, token -> token.isAnnotation(), token -> new IAnnotation(token)); + IParameter parameter = new IParameter(annotations, builder.rebuild(parameterStmt)); + parameter.setType(factory.create(clazz, parameterStmt.get(0))); method.parameters.add(parameter); } } -- Gitee From 57f942e816f0351870a3ec8a95c51a02faec1bad Mon Sep 17 00:00:00 2001 From: chenT Date: Sun, 18 Apr 2021 20:07:38 +0800 Subject: [PATCH 062/121] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8B=93=E5=B1=95?= =?UTF-8?q?=E6=9C=BA=E5=88=B6=EF=BC=8C=E4=BD=BF=E6=8B=93=E5=B1=95=E6=9B=B4?= =?UTF-8?q?=E5=8A=A0=E7=81=B5=E6=B4=BB=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/common/annotation/App.java | 14 ++++++++++++++ .../com/sum/spirit/common/annotation/Native.java | 14 ++++++++++++++ .../com/sum/spirit/common/constants/Constants.java | 1 - .../com/sum/spirit/common/utils/SpringUtils.java | 7 ++++--- .../spirit/core/compile/DefaultElementVisiter.java | 6 +++--- .../compile/action/ElementExpressDeclarer.java | 2 ++ .../core/compile/action/ElementInvokeVisiter.java | 2 ++ .../core/compile/action/ElementTypeDeclarer.java | 2 ++ .../compile/action/ElementVariableTracker.java | 2 ++ .../spirit/core/compile/entity/ElementEvent.java | 2 +- .../compile/linker/AbstractAdaptiveLinker.java | 2 +- .../java/com/sum/spirit/core/lexer/CoreLexer.java | 2 +- .../com/sum/spirit/output/java/JavaBuilder.java | 5 ++--- .../spirit/output/java/action/CommonAction.java | 2 ++ .../spirit/output/java/action/SeparatorAction.java | 2 ++ .../spirit/output/java/action/StatementAction.java | 2 ++ .../output/java/action/StringEqualsAction.java | 2 ++ .../output/java/action/StringLogicAction.java | 2 ++ 18 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 spirit-common/src/main/java/com/sum/spirit/common/annotation/App.java create mode 100644 spirit-common/src/main/java/com/sum/spirit/common/annotation/Native.java diff --git a/spirit-common/src/main/java/com/sum/spirit/common/annotation/App.java b/spirit-common/src/main/java/com/sum/spirit/common/annotation/App.java new file mode 100644 index 00000000..8af61838 --- /dev/null +++ b/spirit-common/src/main/java/com/sum/spirit/common/annotation/App.java @@ -0,0 +1,14 @@ +package com.sum.spirit.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface App { + +} diff --git a/spirit-common/src/main/java/com/sum/spirit/common/annotation/Native.java b/spirit-common/src/main/java/com/sum/spirit/common/annotation/Native.java new file mode 100644 index 00000000..ac015a41 --- /dev/null +++ b/spirit-common/src/main/java/com/sum/spirit/common/annotation/Native.java @@ -0,0 +1,14 @@ +package com.sum.spirit.common.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Native { + +} diff --git a/spirit-common/src/main/java/com/sum/spirit/common/constants/Constants.java b/spirit-common/src/main/java/com/sum/spirit/common/constants/Constants.java index a8afd79b..af44dc76 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/constants/Constants.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/constants/Constants.java @@ -3,7 +3,6 @@ package com.sum.spirit.common.constants; public class Constants { public static final String DEFAULT_CHARSET = "UTF-8"; - public static final String SPIRIT_CORE_PACKAGE = "com.sum.spirit.core"; public static final String INPUT_ARG_KEY = "input"; public static final String OUTPUT_ARG_KEY = "output"; diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/SpringUtils.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/SpringUtils.java index 913f9fc4..eadea9c1 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/SpringUtils.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/SpringUtils.java @@ -1,5 +1,6 @@ package com.sum.spirit.common.utils; +import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -41,14 +42,14 @@ public class SpringUtils implements ApplicationContextAware { return beans; } - public static List getBeansAndSort(Class type, Class... excludedTypes) { + public static List getBeansByExcludedTypes(Class type, Class... excludedTypes) { List beans = getBeansAndSort(type); List> list = Arrays.asList(excludedTypes); return beans.stream().filter((t) -> !list.contains(t.getClass())).collect(Collectors.toList()); } - public static List getBeansAndSort(Class type, String scanPackage) { + public static List getBeansByAnnotation(Class type, Class annotationClass) { List beans = getBeansAndSort(type); - return beans.stream().filter((t) -> t.getClass().getName().startsWith(scanPackage)).collect(Collectors.toList()); + return beans.stream().filter(bean -> bean.getClass().isAnnotationPresent(annotationClass)).collect(Collectors.toList()); } } \ No newline at end of file diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java index 98ee898a..31330d6f 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java @@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; -import com.sum.spirit.common.constants.Constants; +import com.sum.spirit.common.annotation.App; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.ElementAction; @@ -31,7 +31,7 @@ public class DefaultElementVisiter implements ElementVisiter, InitializingBean { @Override public void afterPropertiesSet() throws Exception { - actions = SpringUtils.getBeansAndSort(ElementAction.class, Constants.SPIRIT_CORE_PACKAGE); + actions = SpringUtils.getBeansByAnnotation(ElementAction.class, App.class); } @Override @@ -43,7 +43,7 @@ public class DefaultElementVisiter implements ElementVisiter, InitializingBean { public IVariable visitElement(IClass clazz, MethodContext context, Element element) { try { for (ElementAction action : actions) { - ElementEvent event = new ElementEvent(clazz, element, context); + ElementEvent event = new ElementEvent(clazz, context, element); if (action.isTrigger(event)) { action.handle(event); } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java index 0019a126..2e70f353 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java @@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import com.sum.spirit.common.annotation.App; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.core.api.ElementBuilder; import com.sum.spirit.core.clazz.entity.IClass; @@ -20,6 +21,7 @@ import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; +@App @Component @Order(-80) public class ElementExpressDeclarer extends AbstractElementAction { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementInvokeVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementInvokeVisiter.java index 6547bfd8..f13b910b 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementInvokeVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementInvokeVisiter.java @@ -4,9 +4,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import com.sum.spirit.common.annotation.App; import com.sum.spirit.core.compile.deduce.InvocationVisiter; import com.sum.spirit.core.compile.entity.ElementEvent; +@App @Component @Order(-40) public class ElementInvokeVisiter extends AbstractElementAction { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java index b15828bb..84d8ec58 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java @@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import com.sum.spirit.common.annotation.App; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IClass; @@ -11,6 +12,7 @@ import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Token; +@App @Component @Order(-100) public class ElementTypeDeclarer extends AbstractElementAction { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementVariableTracker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementVariableTracker.java index 822371c0..e1abadbc 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementVariableTracker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementVariableTracker.java @@ -4,9 +4,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import com.sum.spirit.common.annotation.App; import com.sum.spirit.core.compile.deduce.VariableTracker; import com.sum.spirit.core.compile.entity.ElementEvent; +@App @Component @Order(-60) public class ElementVariableTracker extends AbstractElementAction { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity/ElementEvent.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity/ElementEvent.java index b9a0f7cc..4536c735 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity/ElementEvent.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity/ElementEvent.java @@ -14,7 +14,7 @@ public class ElementEvent { this.element = element; } - public ElementEvent(IClass clazz, Element element, MethodContext context) { + public ElementEvent(IClass clazz, MethodContext context, Element element) { this.clazz = clazz; this.element = element; this.context = context; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java index 08f0405a..8738e595 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java @@ -18,7 +18,7 @@ public abstract class AbstractAdaptiveLinker implements ClassLinker, Initializin @Override public void afterPropertiesSet() throws Exception { - linkers = SpringUtils.getBeansAndSort(ClassLinker.class, getClass());// 排除自己 + linkers = SpringUtils.getBeansByExcludedTypes(ClassLinker.class, getClass());// 排除自己 } public ClassLinker getLinker(IType type) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java index 73afd37c..4afde66f 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java @@ -34,7 +34,7 @@ public class CoreLexer extends AbstractCharsHandler implements Lexer, Initializi @Override public void afterPropertiesSet() throws Exception { - actions = SpringUtils.getBeansAndSort(AbstractLexerAction.class, BorderAction.class); + actions = SpringUtils.getBeansByExcludedTypes(AbstractLexerAction.class, BorderAction.class); } /** diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java index 00eb5d9e..488e9a8c 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java @@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; +import com.sum.spirit.common.annotation.Native; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.CodeBuilder; @@ -23,19 +24,17 @@ import com.sum.spirit.core.element.entity.Element; @DependsOn("springUtils") public class JavaBuilder implements CodeBuilder, InitializingBean { - public static final String JAVA_PACKAGE = "com.sum.spirit.output.java"; public static final String IMPLEMENTS_KEYWORD = "implements"; public static final String SYNCHRONIZED_KEYWORD = "synchronized"; public static final String FINAL_KEYWORD = "final"; @Autowired public AutoImporter importer; - public List actions; @Override public void afterPropertiesSet() throws Exception { - actions = SpringUtils.getBeansAndSort(ElementAction.class, JAVA_PACKAGE); + actions = SpringUtils.getBeansByAnnotation(ElementAction.class, Native.class); } @Override diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java index 7808220f..2810577b 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java @@ -4,6 +4,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.google.common.collect.Lists; +import com.sum.spirit.common.annotation.Native; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.compile.action.AbstractElementAction; @@ -13,6 +14,7 @@ import com.sum.spirit.core.element.entity.Token; import com.sum.spirit.core.element.utils.StmtVisiter; import com.sum.spirit.lib.Maps; +@Native @Component @Order(-100) public class CommonAction extends AbstractElementAction { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java index e06eec70..d4295e0a 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/SeparatorAction.java @@ -3,6 +3,7 @@ package com.sum.spirit.output.java.action; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import com.sum.spirit.common.annotation.Native; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.compile.action.AbstractElementAction; @@ -11,6 +12,7 @@ import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; +@Native @Component @Order(-20) public class SeparatorAction extends AbstractElementAction { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java index 4f28dd27..e39ae591 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java @@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import com.sum.spirit.common.annotation.Native; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.enums.TokenTypeEnum; @@ -25,6 +26,7 @@ import com.sum.spirit.core.element.entity.Token; import com.sum.spirit.output.java.JavaBuilder; import com.sum.spirit.output.java.utils.TypeUtils; +@Native @Component @Order(-40) public class StatementAction extends AbstractElementAction { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java index 663ab004..ba109123 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java @@ -7,6 +7,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import com.sum.spirit.common.annotation.Native; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.entity.IClass; @@ -16,6 +17,7 @@ import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; import com.sum.spirit.output.java.utils.TypeUtils; +@Native @Component @Order(-80) public class StringEqualsAction extends AbstractTreeElementAction { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java index d38ea329..5a26d496 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java @@ -7,6 +7,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import com.sum.spirit.common.annotation.Native; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.entity.IClass; @@ -16,6 +17,7 @@ import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; import com.sum.spirit.output.java.utils.TypeUtils; +@Native @Component @Order(-60) public class StringLogicAction extends AbstractTreeElementAction { -- Gitee From d2e63f6fe4b78bd04cd79b708a70ae6943d465e3 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 27 Apr 2021 15:09:42 +0800 Subject: [PATCH 063/121] =?UTF-8?q?=E4=BF=AE=E6=94=B9classLinker=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/api/ClassLinker.java | 2 - .../spirit/core/compile/AppTypeFactory.java | 2 +- .../sum/spirit/core/compile/CoreCompiler.java | 2 +- .../core/compile/deduce/TypeDerivator.java | 2 +- .../linker/AbstractAdaptiveLinker.java | 80 ------------------- ...veLinker.java => AdaptiveClassLinker.java} | 65 ++++++++++++++- .../core/compile/linker/AppClassLinker.java | 5 -- ...er.java => AbstractNativeClassLinker.java} | 7 +- ...tiveLinker.java => NativeClassLinker.java} | 2 +- .../starter/kit/core/CustomClassLoader.java | 2 +- 10 files changed, 69 insertions(+), 100 deletions(-) delete mode 100644 spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java rename spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/{AdaptiveLinker.java => AdaptiveClassLinker.java} (65%) rename spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/{AbstractNativeLinker.java => AbstractNativeClassLinker.java} (92%) rename spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/{NativeLinker.java => NativeClassLinker.java} (95%) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassLinker.java index 2427f4df..33075203 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassLinker.java @@ -6,8 +6,6 @@ import com.sum.spirit.core.clazz.entity.IType; public interface ClassLinker { - boolean isHandle(IType type); - T toClass(IType type); int getTypeVariableIndex(IType type, String genericName); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java index a493c584..425e11ce 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java @@ -22,8 +22,8 @@ import com.sum.spirit.core.element.entity.Token; import cn.hutool.core.lang.Assert; -@Component @Primary +@Component public class AppTypeFactory extends AbstractTypeFactory { @Autowired diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/CoreCompiler.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/CoreCompiler.java index f919b91f..5a8fb927 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/CoreCompiler.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/CoreCompiler.java @@ -14,8 +14,8 @@ import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.utils.TypeUtils; import com.sum.spirit.core.element.entity.Document; -@Component @Primary +@Component public class CoreCompiler implements Compiler { @Autowired diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java index 4c70c355..69594f78 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java @@ -14,8 +14,8 @@ import com.sum.spirit.core.clazz.utils.TypeVisiter; import cn.hutool.core.lang.Assert; -@Component @Primary +@Component public class TypeDerivator { @Autowired diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java deleted file mode 100644 index 8738e595..00000000 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AbstractAdaptiveLinker.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.sum.spirit.core.compile.linker; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.InitializingBean; - -import com.sum.spirit.common.enums.ModifierEnum; -import com.sum.spirit.common.utils.Lists; -import com.sum.spirit.common.utils.SpringUtils; -import com.sum.spirit.core.api.ClassLinker; -import com.sum.spirit.core.clazz.entity.IType; -import com.sum.spirit.core.clazz.utils.StaticTypes; - -public abstract class AbstractAdaptiveLinker implements ClassLinker, InitializingBean { - - public List linkers; - - @Override - public void afterPropertiesSet() throws Exception { - linkers = SpringUtils.getBeansByExcludedTypes(ClassLinker.class, getClass());// 排除自己 - } - - public ClassLinker getLinker(IType type) { - return Lists.findOne(linkers, linker -> linker.isHandle(type)); - } - - @Override - public boolean isHandle(IType type) { - return getLinker(type) != null; - } - - @Override - public T toClass(IType type) { - return getLinker(type).toClass(type); - } - - @Override - public int getTypeVariableIndex(IType type, String genericName) { - return getLinker(type).getTypeVariableIndex(type, genericName); - } - - @Override - public IType getSuperType(IType type) { - if (type.isPrimitive()) { - return null; - } - if (type.isArray()) { - return StaticTypes.OBJECT; - } - if (StaticTypes.OBJECT.equals(type)) { - return null; - } - // 如果不存在父类,则返回Object - IType superType = getLinker(type).getSuperType(type); - if (superType == null) { - return StaticTypes.OBJECT; - } - int modifiers = type.getModifiers(); - if (modifiers == ModifierEnum.THIS.value || modifiers == ModifierEnum.SUPER.value) { - superType.setModifiers(ModifierEnum.SUPER.value); - - } else if (modifiers == ModifierEnum.PUBLIC.value) { - superType.setModifiers(ModifierEnum.PUBLIC.value); - } - return superType; - } - - @Override - public List getInterfaceTypes(IType type) { - if (type.isPrimitive()) { - return new ArrayList<>(); - } - if (type.isArray()) { - return new ArrayList<>(); - } - return getLinker(type).getInterfaceTypes(type); - } - -} diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java similarity index 65% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java rename to spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java index adb0ead4..d8caca72 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java @@ -1,6 +1,8 @@ package com.sum.spirit.core.compile.linker; +import java.util.ArrayList; import java.util.List; +import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.DependsOn; @@ -8,6 +10,8 @@ import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.KeywordEnum; +import com.sum.spirit.common.enums.ModifierEnum; +import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.StaticTypes; @@ -15,10 +19,10 @@ import com.sum.spirit.core.compile.deduce.TypeDerivator; import cn.hutool.core.lang.Assert; -@Component @Primary +@Component @DependsOn("springUtils") -public class AdaptiveLinker extends AbstractAdaptiveLinker { +public class AdaptiveClassLinker implements ClassLinker { public static final String ARRAY_LENGTH = "length"; @@ -26,6 +30,63 @@ public class AdaptiveLinker extends AbstractAdaptiveLinker { public TypeFactory factory; @Autowired public TypeDerivator derivator; + @Autowired + public Map linkers; + + public ClassLinker getLinker(IType type) { + if (!type.isNative()) { + return linkers.get("appClassLinker"); + } else { + return linkers.get("nativeClassLinker"); + } + } + + @Override + public T toClass(IType type) { + return getLinker(type).toClass(type); + } + + @Override + public int getTypeVariableIndex(IType type, String genericName) { + return getLinker(type).getTypeVariableIndex(type, genericName); + } + + @Override + public IType getSuperType(IType type) { + if (type.isPrimitive()) { + return null; + } + if (type.isArray()) { + return StaticTypes.OBJECT; + } + if (StaticTypes.OBJECT.equals(type)) { + return null; + } + // 如果不存在父类,则返回Object + IType superType = getLinker(type).getSuperType(type); + if (superType == null) { + return StaticTypes.OBJECT; + } + int modifiers = type.getModifiers(); + if (modifiers == ModifierEnum.THIS.value || modifiers == ModifierEnum.SUPER.value) { + superType.setModifiers(ModifierEnum.SUPER.value); + + } else if (modifiers == ModifierEnum.PUBLIC.value) { + superType.setModifiers(ModifierEnum.PUBLIC.value); + } + return superType; + } + + @Override + public List getInterfaceTypes(IType type) { + if (type.isPrimitive()) { + return new ArrayList<>(); + } + if (type.isArray()) { + return new ArrayList<>(); + } + return getLinker(type).getInterfaceTypes(type); + } @Override public IType visitField(IType type, String fieldName) throws NoSuchFieldException { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java index f662d598..ad09a735 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java @@ -34,11 +34,6 @@ public class AppClassLinker implements ClassLinker { @Autowired public TypeDerivator derivator; - @Override - public boolean isHandle(IType type) { - return !type.isNative(); - } - @Override @SuppressWarnings("unchecked") public T toClass(IType type) { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeLinker.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeClassLinker.java similarity index 92% rename from spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeLinker.java rename to spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeClassLinker.java index 156ad106..f76a0b8d 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeLinker.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeClassLinker.java @@ -13,7 +13,7 @@ import com.sum.spirit.output.java.ExtClassLoader; import com.sum.spirit.output.java.deduce.NativeDerivator; import com.sum.spirit.output.java.deduce.NativeTypeFactory; -public abstract class AbstractNativeLinker implements ClassLinker { +public abstract class AbstractNativeClassLinker implements ClassLinker { @Autowired public ExtClassLoader classLoader; @@ -22,11 +22,6 @@ public abstract class AbstractNativeLinker implements ClassLinker { @Autowired public NativeDerivator derivator; - @Override - public boolean isHandle(IType type) { - return type.isNative(); - } - @Override @SuppressWarnings("unchecked") public T toClass(IType type) { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeLinker.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java similarity index 95% rename from spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeLinker.java rename to spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java index 1638cb6a..b0dae3d8 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeLinker.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java @@ -17,7 +17,7 @@ import cn.hutool.core.lang.Assert; @Component @Order(-80) -public class NativeLinker extends AbstractNativeLinker { +public class NativeClassLinker extends AbstractNativeClassLinker { @Override public IType visitField(IType type, String fieldName) throws NoSuchFieldException { diff --git a/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/CustomClassLoader.java b/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/CustomClassLoader.java index afcd25f2..bcaefc09 100644 --- a/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/CustomClassLoader.java +++ b/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/core/CustomClassLoader.java @@ -14,8 +14,8 @@ import com.sum.spirit.common.utils.URLFileUtils; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.compile.AppClassLoader; -@Component @Primary +@Component @DependsOn("configUtils") public class CustomClassLoader extends AppClassLoader { -- Gitee From 7e107f37d7b2ef97304c093c65bdae9dc5e51a04 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 27 Apr 2021 15:31:11 +0800 Subject: [PATCH 064/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/api/ClassResolver.java | 5 +++++ .../spirit/core/clazz/DefaultClassResolver.java | 13 +++++++++++-- .../sum/spirit/core/clazz/entity/IClass.java | 6 ++---- .../core/clazz/frame/ClassResolverEntity.java | 17 +++++++++++++++++ .../spirit/core/clazz/frame/ImportEntity.java | 8 +++----- 5 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ClassResolverEntity.java diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ClassResolver.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ClassResolver.java index cde127f6..54d73394 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ClassResolver.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ClassResolver.java @@ -1,5 +1,6 @@ package com.sum.spirit.core.api; +import java.util.List; import java.util.Map; import com.sum.spirit.core.clazz.entity.IClass; @@ -9,4 +10,8 @@ public interface ClassResolver { Map resolve(String packageStr, Document document); + TypeFactory getTypeFactory(); + + List getImportSelectors(); + } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java index ffca8ef3..5314c988 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java @@ -106,8 +106,7 @@ public class DefaultClassResolver implements ClassResolver { clazz.packageStr = packageStr; clazz.fields = fields; clazz.methods = methods; - clazz.factory = factory; - clazz.importSelectors = importSelectors; + clazz.classResolver = this; } public void readRootElement(IClass clazz) { @@ -125,4 +124,14 @@ public class DefaultClassResolver implements ClassResolver { } } + @Override + public TypeFactory getTypeFactory() { + return factory; + } + + @Override + public List getImportSelectors() { + return importSelectors; + } + } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java index ba638d37..c7f079bc 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java @@ -6,7 +6,6 @@ import java.util.stream.Collectors; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.utils.Lists; -import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.frame.ImportEntity; import com.sum.spirit.core.clazz.utils.TypeUtils; import com.sum.spirit.core.element.entity.Element; @@ -19,7 +18,6 @@ public class IClass extends ImportEntity { public String packageStr; public List fields; public List methods; - public TypeFactory factory; public IClass(List imports, List annotations, Element element) { super(imports, annotations, element); @@ -74,7 +72,7 @@ public class IClass extends ImportEntity { public IType getSuperType() {// 注意:这里返回的是Super Token token = element.getKeywordParam(KeywordEnum.EXTENDS.value);// 这里返回的,可以是泛型格式,而不是className if (token != null) { - return factory.create(this, token); + return classResolver.getTypeFactory().create(this, token); } return null; } @@ -82,7 +80,7 @@ public class IClass extends ImportEntity { public List getInterfaceTypes() { List interfaces = new ArrayList<>(); for (Token token : element.getKeywordParams(KeywordEnum.IMPLS.value)) { - interfaces.add(factory.create(this, token)); + interfaces.add(classResolver.getTypeFactory().create(this, token)); } return interfaces; } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ClassResolverEntity.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ClassResolverEntity.java new file mode 100644 index 00000000..1219fdcb --- /dev/null +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ClassResolverEntity.java @@ -0,0 +1,17 @@ +package com.sum.spirit.core.clazz.frame; + +import java.util.List; + +import com.sum.spirit.core.api.ClassResolver; +import com.sum.spirit.core.clazz.entity.IAnnotation; +import com.sum.spirit.core.element.entity.Element; + +public class ClassResolverEntity extends AnnotationEntity { + + public ClassResolver classResolver; + + public ClassResolverEntity(List annotations, Element element) { + super(annotations, element); + } + +} diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java index c748cd98..80b15e29 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java @@ -6,7 +6,6 @@ import java.util.stream.Collectors; import com.sum.spirit.common.enums.PrimitiveEnum; import com.sum.spirit.common.utils.Lists; -import com.sum.spirit.core.api.ImportSelector; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.clazz.entity.Import; import com.sum.spirit.core.clazz.utils.TypeUtils; @@ -14,10 +13,9 @@ import com.sum.spirit.core.element.entity.Element; import cn.hutool.core.lang.Assert; -public abstract class ImportEntity extends AnnotationEntity { +public abstract class ImportEntity extends ClassResolverEntity { public List imports; - public List importSelectors; public ImportEntity(List imports, List annotations, Element element) { super(annotations, element); @@ -100,11 +98,11 @@ public abstract class ImportEntity extends AnnotationEntity { } public String findClassNameByLoader(String simpleName) { - return Lists.collectOne(importSelectors, importSelector -> importSelector.findClassName(simpleName)); + return Lists.collectOne(classResolver.getImportSelectors(), importSelector -> importSelector.findClassName(simpleName)); } public boolean shouldImport(String selfName, String className) { - Boolean flag = Lists.collectOne(importSelectors, importSelector -> importSelector.isHandle(className), + Boolean flag = Lists.collectOne(classResolver.getImportSelectors(), importSelector -> importSelector.isHandle(className), importSelector -> importSelector.shouldImport(selfName, className)); return flag == null ? true : flag; } -- Gitee From 51fb36e44fe85693251e37caa8c0836bf37bf6af Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 27 Apr 2021 16:39:31 +0800 Subject: [PATCH 065/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/core/api/ClassVisiter.java | 4 ++++ .../com/sum/spirit/core/compile/DefaultClassVisiter.java | 1 + .../com/sum/spirit/core/compile/linker/AppClassLinker.java | 7 ++----- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassVisiter.java index 0d546bf0..84731e0f 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/api/ClassVisiter.java @@ -1,6 +1,8 @@ package com.sum.spirit.core.api; import com.sum.spirit.core.clazz.entity.IClass; +import com.sum.spirit.core.clazz.entity.IType; +import com.sum.spirit.core.clazz.frame.MemberEntity; public interface ClassVisiter { @@ -8,4 +10,6 @@ public interface ClassVisiter { void visitClass(IClass clazz); + IType visitMember(IClass clazz, MemberEntity member); + } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java index 24d7c49c..ea65c2cc 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java @@ -78,6 +78,7 @@ public class DefaultClassVisiter implements ClassVisiter { } } + @Override public IType visitMember(IClass clazz, MemberEntity member) { ObjectUtils.lock(member); // 防止循环依赖 IType type = member.getType(); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java index ad09a735..94315602 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java @@ -9,14 +9,13 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.utils.Lists; import com.sum.spirit.core.api.ClassLinker; -import com.sum.spirit.core.api.TypeFactory; +import com.sum.spirit.core.api.ClassVisiter; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IField; import com.sum.spirit.core.clazz.entity.IMethod; import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.AppClassLoader; -import com.sum.spirit.core.compile.DefaultClassVisiter; import com.sum.spirit.core.compile.deduce.TypeDerivator; import cn.hutool.core.lang.Assert; @@ -28,9 +27,7 @@ public class AppClassLinker implements ClassLinker { @Autowired public AppClassLoader classLoader; @Autowired - public TypeFactory factory; - @Autowired - public DefaultClassVisiter visiter; + public ClassVisiter visiter; @Autowired public TypeDerivator derivator; -- Gitee From d3bda6e19cc26a873bcbcaea37adc0871e4ba862 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 27 Apr 2021 16:49:45 +0800 Subject: [PATCH 066/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/clazz/frame/ClassResolverEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ClassResolverEntity.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ClassResolverEntity.java index 1219fdcb..476e2c91 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ClassResolverEntity.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ClassResolverEntity.java @@ -6,7 +6,7 @@ import com.sum.spirit.core.api.ClassResolver; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.element.entity.Element; -public class ClassResolverEntity extends AnnotationEntity { +public abstract class ClassResolverEntity extends AnnotationEntity { public ClassResolver classResolver; -- Gitee From e9a4087cf441bda18fee8a630aff9933051a5094 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 27 Apr 2021 16:58:19 +0800 Subject: [PATCH 067/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/clazz/utils/StaticTypes.java | 42 ++++++++----------- .../spirit/core/clazz/utils/TypeBuilder.java | 17 ++++++++ 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils/StaticTypes.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils/StaticTypes.java index a958cfd0..8bbe3d17 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils/StaticTypes.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils/StaticTypes.java @@ -2,7 +2,6 @@ package com.sum.spirit.core.clazz.utils; import java.util.Map; -import com.sum.spirit.common.enums.ModifierEnum; import com.sum.spirit.common.enums.PrimitiveEnum; import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.StaticTypesCtor; @@ -52,24 +51,24 @@ public class StaticTypes { public static final IType WILDCARD; static { - VOID = createTypeByPrimitiveEnum(PrimitiveEnum.VOID); - BOOLEAN = createTypeByPrimitiveEnum(PrimitiveEnum.BOOLEAN); - CHAR = createTypeByPrimitiveEnum(PrimitiveEnum.CHAR); - BYTE = createTypeByPrimitiveEnum(PrimitiveEnum.BYTE); - SHORT = createTypeByPrimitiveEnum(PrimitiveEnum.SHORT); - INT = createTypeByPrimitiveEnum(PrimitiveEnum.INT); - LONG = createTypeByPrimitiveEnum(PrimitiveEnum.LONG); - FLOAT = createTypeByPrimitiveEnum(PrimitiveEnum.FLOAT); - DOUBLE = createTypeByPrimitiveEnum(PrimitiveEnum.DOUBLE); - - BOOLEAN_ARRAY = createTypeByPrimitiveEnum(PrimitiveEnum.BOOLEAN_ARRAY); - CHAR_ARRAY = createTypeByPrimitiveEnum(PrimitiveEnum.CHAR_ARRAY); - BYTE_ARRAY = createTypeByPrimitiveEnum(PrimitiveEnum.BYTE_ARRAY); - SHORT_ARRAY = createTypeByPrimitiveEnum(PrimitiveEnum.SHORT_ARRAY); - INT_ARRAY = createTypeByPrimitiveEnum(PrimitiveEnum.INT_ARRAY); - LONG_ARRAY = createTypeByPrimitiveEnum(PrimitiveEnum.INT_ARRAY); - FLOAT_ARRAY = createTypeByPrimitiveEnum(PrimitiveEnum.FLOAT_ARRAY); - DOUBLE_ARRAY = createTypeByPrimitiveEnum(PrimitiveEnum.DOUBLE_ARRAY); + VOID = TypeBuilder.build(PrimitiveEnum.VOID); + BOOLEAN = TypeBuilder.build(PrimitiveEnum.BOOLEAN); + CHAR = TypeBuilder.build(PrimitiveEnum.CHAR); + BYTE = TypeBuilder.build(PrimitiveEnum.BYTE); + SHORT = TypeBuilder.build(PrimitiveEnum.SHORT); + INT = TypeBuilder.build(PrimitiveEnum.INT); + LONG = TypeBuilder.build(PrimitiveEnum.LONG); + FLOAT = TypeBuilder.build(PrimitiveEnum.FLOAT); + DOUBLE = TypeBuilder.build(PrimitiveEnum.DOUBLE); + + BOOLEAN_ARRAY = TypeBuilder.build(PrimitiveEnum.BOOLEAN_ARRAY); + CHAR_ARRAY = TypeBuilder.build(PrimitiveEnum.CHAR_ARRAY); + BYTE_ARRAY = TypeBuilder.build(PrimitiveEnum.BYTE_ARRAY); + SHORT_ARRAY = TypeBuilder.build(PrimitiveEnum.SHORT_ARRAY); + INT_ARRAY = TypeBuilder.build(PrimitiveEnum.INT_ARRAY); + LONG_ARRAY = TypeBuilder.build(PrimitiveEnum.INT_ARRAY); + FLOAT_ARRAY = TypeBuilder.build(PrimitiveEnum.FLOAT_ARRAY); + DOUBLE_ARRAY = TypeBuilder.build(PrimitiveEnum.DOUBLE_ARRAY); StaticTypesCtor ctor = SpringUtils.getBean(StaticTypesCtor.class); Assert.notNull(ctor, "Static types ctor must be provided!"); @@ -96,11 +95,6 @@ public class StaticTypes { WILDCARD = typeMap.get("WILDCARD"); } - public static IType createTypeByPrimitiveEnum(PrimitiveEnum primitiveEnum) { - return IType.builder().className(primitiveEnum.className).simpleName(primitiveEnum.simpleName).typeName(primitiveEnum.typeName) - .isPrimitive(primitiveEnum.isPrimitive).isArray(primitiveEnum.isArray).modifiers(ModifierEnum.PUBLIC.value).build(); - } - public static IType getBoxType(String className) { if (VOID.getClassName().equals(className)) { return VOID_BOX; diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils/TypeBuilder.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils/TypeBuilder.java index abb28440..52e83a73 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils/TypeBuilder.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/utils/TypeBuilder.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Collections; import com.sum.spirit.common.enums.ModifierEnum; +import com.sum.spirit.common.enums.PrimitiveEnum; import com.sum.spirit.core.clazz.entity.IType; public class TypeBuilder { @@ -25,6 +26,22 @@ public class TypeBuilder { return type; } + public static IType build(PrimitiveEnum primitiveEnum) { + IType type = new IType(); + type.setClassName(primitiveEnum.className); + type.setSimpleName(primitiveEnum.simpleName); + type.setTypeName(primitiveEnum.typeName); + type.setGenericName(null); + type.setPrimitive(primitiveEnum.isPrimitive); + type.setArray(primitiveEnum.isArray); + type.setNull(false); + type.setWildcard(false); + type.setNative(false); + type.setModifiers(ModifierEnum.PUBLIC.value); + type.setGenericTypes(new ArrayList<>()); + return type; + } + public static IType copy(IType oldType) { IType newType = new IType(); newType.setClassName(oldType.getClassName()); -- Gitee From 376c9dcc8d1ba5752b1067ad57a7355ef984a6db Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 27 Apr 2021 17:13:38 +0800 Subject: [PATCH 068/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/compile/AppTypeFactory.java | 4 ++-- .../com/sum/spirit/core/compile/DefaultElementVisiter.java | 4 ++-- .../spirit/core/compile/action/ElementExpressDeclarer.java | 4 ++-- .../{SimpleSectionDeducer.java => FragmentDeducer.java} | 2 +- .../sum/spirit/core/compile/deduce/InvocationVisiter.java | 6 +++--- .../output/java/action/AbstractTreeElementAction.java | 4 ++-- .../com/sum/spirit/output/java/action/StatementAction.java | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) rename spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/{SimpleSectionDeducer.java => FragmentDeducer.java} (97%) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java index 425e11ce..1486ac38 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java @@ -15,7 +15,7 @@ import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.StaticTypes; import com.sum.spirit.core.clazz.utils.TypeUtils; -import com.sum.spirit.core.compile.deduce.SimpleSectionDeducer; +import com.sum.spirit.core.compile.deduce.FragmentDeducer; import com.sum.spirit.core.compile.deduce.TypeDerivator; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @@ -29,7 +29,7 @@ public class AppTypeFactory extends AbstractTypeFactory { @Autowired public AppClassLoader classLoader; @Autowired - public SimpleSectionDeducer deducer; + public FragmentDeducer deducer; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java index 31330d6f..a1d32017 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java @@ -14,7 +14,7 @@ import com.sum.spirit.core.api.ElementAction; import com.sum.spirit.core.api.ElementVisiter; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IVariable; -import com.sum.spirit.core.compile.deduce.SimpleSectionDeducer; +import com.sum.spirit.core.compile.deduce.FragmentDeducer; import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.compile.entity.MethodContext; import com.sum.spirit.core.element.entity.Element; @@ -26,7 +26,7 @@ import com.sum.spirit.core.element.entity.Token; public class DefaultElementVisiter implements ElementVisiter, InitializingBean { @Autowired - public SimpleSectionDeducer deducer; + public FragmentDeducer deducer; public List actions; @Override diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java index 2e70f353..2db2349b 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java @@ -11,7 +11,7 @@ import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.entity.IVariable; import com.sum.spirit.core.compile.DefaultElementVisiter; -import com.sum.spirit.core.compile.deduce.SimpleSectionDeducer; +import com.sum.spirit.core.compile.deduce.FragmentDeducer; import com.sum.spirit.core.compile.deduce.InvocationVisiter; import com.sum.spirit.core.compile.deduce.TypeDerivator; import com.sum.spirit.core.compile.deduce.VariableTracker; @@ -35,7 +35,7 @@ public class ElementExpressDeclarer extends AbstractElementAction { @Autowired public InvocationVisiter visiter; @Autowired - public SimpleSectionDeducer deducer; + public FragmentDeducer deducer; @Autowired public TypeDerivator derivator; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleSectionDeducer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/FragmentDeducer.java similarity index 97% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleSectionDeducer.java rename to spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/FragmentDeducer.java index cfe7c198..48056d5f 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/SimpleSectionDeducer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/FragmentDeducer.java @@ -13,7 +13,7 @@ import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @Component -public class SimpleSectionDeducer { +public class FragmentDeducer { @Autowired public TreeBuilder builder; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java index 11eea308..3a056933 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java @@ -19,11 +19,11 @@ import com.sum.spirit.core.element.utils.StmtVisiter; public class InvocationVisiter { @Autowired - public SimpleSectionDeducer deducer; + public TypeFactory factory; @Autowired - public ClassLinker linker; + public FragmentDeducer deducer; @Autowired - public TypeFactory factory; + public ClassLinker linker; @Autowired public TypeDerivator derivator; diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java index d06e8133..562dd0d1 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/AbstractTreeElementAction.java @@ -8,7 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.action.AbstractElementAction; -import com.sum.spirit.core.compile.deduce.SimpleSectionDeducer; +import com.sum.spirit.core.compile.deduce.FragmentDeducer; import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @@ -25,7 +25,7 @@ public abstract class AbstractTreeElementAction extends AbstractElementAction { public static final String NEXT_TYPE = "NEXT_TYPE"; @Autowired - public SimpleSectionDeducer deducer; + public FragmentDeducer deducer; @Override public void handle(ElementEvent event) { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java index e39ae591..c9d5d836 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java @@ -17,7 +17,7 @@ import com.sum.spirit.core.clazz.entity.IField; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.AutoImporter; import com.sum.spirit.core.compile.action.AbstractElementAction; -import com.sum.spirit.core.compile.deduce.SimpleSectionDeducer; +import com.sum.spirit.core.compile.deduce.FragmentDeducer; import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.element.DefaultElementBuilder; import com.sum.spirit.core.element.entity.Element; @@ -34,7 +34,7 @@ public class StatementAction extends AbstractElementAction { @Autowired public DefaultElementBuilder builder; @Autowired - public SimpleSectionDeducer deducer; + public FragmentDeducer deducer; @Autowired public AutoImporter importer; -- Gitee From bfb4ff6553999e9664ef4c38030da07e0280140e Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 27 Apr 2021 18:39:31 +0800 Subject: [PATCH 069/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/api/ClassResolver.java | 5 ----- .../java/com/sum/spirit/core/api/ResolverContext.java | 11 +++++++++++ .../sum/spirit/core/clazz/DefaultClassResolver.java | 5 +++-- .../java/com/sum/spirit/core/clazz/entity/IClass.java | 4 ++-- .../{ClassResolverEntity.java => ContextEntity.java} | 8 ++++---- .../com/sum/spirit/core/clazz/frame/ImportEntity.java | 6 +++--- 6 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ResolverContext.java rename spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/{ClassResolverEntity.java => ContextEntity.java} (47%) diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ClassResolver.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ClassResolver.java index 54d73394..cde127f6 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ClassResolver.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ClassResolver.java @@ -1,6 +1,5 @@ package com.sum.spirit.core.api; -import java.util.List; import java.util.Map; import com.sum.spirit.core.clazz.entity.IClass; @@ -10,8 +9,4 @@ public interface ClassResolver { Map resolve(String packageStr, Document document); - TypeFactory getTypeFactory(); - - List getImportSelectors(); - } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ResolverContext.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ResolverContext.java new file mode 100644 index 00000000..a334cb5d --- /dev/null +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ResolverContext.java @@ -0,0 +1,11 @@ +package com.sum.spirit.core.api; + +import java.util.List; + +public interface ResolverContext { + + TypeFactory getTypeFactory(); + + List getImportSelectors(); + +} diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java index 5314c988..8c6b4ad9 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java @@ -10,6 +10,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.core.api.ClassResolver; +import com.sum.spirit.core.api.ResolverContext; import com.sum.spirit.core.api.ElementBuilder; import com.sum.spirit.core.api.ImportSelector; import com.sum.spirit.core.api.TypeFactory; @@ -23,7 +24,7 @@ import com.sum.spirit.core.element.entity.Document; import com.sum.spirit.core.element.entity.Element; @Component -public class DefaultClassResolver implements ClassResolver { +public class DefaultClassResolver implements ClassResolver, ResolverContext { @Autowired public ElementBuilder builder; @@ -106,7 +107,7 @@ public class DefaultClassResolver implements ClassResolver { clazz.packageStr = packageStr; clazz.fields = fields; clazz.methods = methods; - clazz.classResolver = this; + clazz.context = this; } public void readRootElement(IClass clazz) { diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java index c7f079bc..04b0072d 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java @@ -72,7 +72,7 @@ public class IClass extends ImportEntity { public IType getSuperType() {// 注意:这里返回的是Super Token token = element.getKeywordParam(KeywordEnum.EXTENDS.value);// 这里返回的,可以是泛型格式,而不是className if (token != null) { - return classResolver.getTypeFactory().create(this, token); + return context.getTypeFactory().create(this, token); } return null; } @@ -80,7 +80,7 @@ public class IClass extends ImportEntity { public List getInterfaceTypes() { List interfaces = new ArrayList<>(); for (Token token : element.getKeywordParams(KeywordEnum.IMPLS.value)) { - interfaces.add(classResolver.getTypeFactory().create(this, token)); + interfaces.add(context.getTypeFactory().create(this, token)); } return interfaces; } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ClassResolverEntity.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ContextEntity.java similarity index 47% rename from spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ClassResolverEntity.java rename to spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ContextEntity.java index 476e2c91..95a10b9e 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ClassResolverEntity.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ContextEntity.java @@ -2,15 +2,15 @@ package com.sum.spirit.core.clazz.frame; import java.util.List; -import com.sum.spirit.core.api.ClassResolver; +import com.sum.spirit.core.api.ResolverContext; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.element.entity.Element; -public abstract class ClassResolverEntity extends AnnotationEntity { +public abstract class ContextEntity extends AnnotationEntity { - public ClassResolver classResolver; + public ResolverContext context; - public ClassResolverEntity(List annotations, Element element) { + public ContextEntity(List annotations, Element element) { super(annotations, element); } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java index 80b15e29..152bf910 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java @@ -13,7 +13,7 @@ import com.sum.spirit.core.element.entity.Element; import cn.hutool.core.lang.Assert; -public abstract class ImportEntity extends ClassResolverEntity { +public abstract class ImportEntity extends ContextEntity { public List imports; @@ -98,11 +98,11 @@ public abstract class ImportEntity extends ClassResolverEntity { } public String findClassNameByLoader(String simpleName) { - return Lists.collectOne(classResolver.getImportSelectors(), importSelector -> importSelector.findClassName(simpleName)); + return Lists.collectOne(context.getImportSelectors(), importSelector -> importSelector.findClassName(simpleName)); } public boolean shouldImport(String selfName, String className) { - Boolean flag = Lists.collectOne(classResolver.getImportSelectors(), importSelector -> importSelector.isHandle(className), + Boolean flag = Lists.collectOne(context.getImportSelectors(), importSelector -> importSelector.isHandle(className), importSelector -> importSelector.shouldImport(selfName, className)); return flag == null ? true : flag; } -- Gitee From 23384e818fb531ceed122ef61635c7fe5719301d Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Tue, 27 Apr 2021 18:40:55 +0800 Subject: [PATCH 070/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/clazz/DefaultClassResolver.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java index 8c6b4ad9..0a06956a 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java @@ -31,7 +31,7 @@ public class DefaultClassResolver implements ClassResolver, ResolverContext { @Autowired public TypeFactory factory; @Autowired - public List importSelectors; + public List selectors; @Override public Map resolve(String packageStr, Document document) { @@ -132,7 +132,7 @@ public class DefaultClassResolver implements ClassResolver, ResolverContext { @Override public List getImportSelectors() { - return importSelectors; + return selectors; } } -- Gitee From acc600c469168e88b180f18397c738e7936ea358 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Wed, 28 Apr 2021 12:02:19 +0800 Subject: [PATCH 071/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java index d8caca72..e4b801c9 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java @@ -5,7 +5,6 @@ import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @@ -21,7 +20,6 @@ import cn.hutool.core.lang.Assert; @Primary @Component -@DependsOn("springUtils") public class AdaptiveClassLinker implements ClassLinker { public static final String ARRAY_LENGTH = "length"; -- Gitee From 65b08ac0a228bc8059abc2c892185ae21fe8475d Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Wed, 28 Apr 2021 17:19:23 +0800 Subject: [PATCH 072/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/core/compile/deduce/VariableTracker.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java index 30ad1a18..13177a65 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java @@ -6,12 +6,10 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.core.api.ClassLinker; -import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.entity.IVariable; -import com.sum.spirit.core.compile.DefaultClassVisiter; import com.sum.spirit.core.compile.entity.MethodContext; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.utils.StmtVisiter; @@ -22,13 +20,9 @@ import cn.hutool.core.lang.Assert; public class VariableTracker { @Autowired - public DefaultClassVisiter visiter; + public TypeDerivator derivator; @Autowired public ClassLinker linker; - @Autowired - public TypeFactory factory; - @Autowired - public TypeDerivator derivator; public void visit(IClass clazz, MethodContext context, Statement statement) { StmtVisiter.visit(statement, stmt -> { -- Gitee From 59e890f8bfb01ce74c5b471a799ebefd87f82041 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Wed, 28 Apr 2021 17:32:47 +0800 Subject: [PATCH 073/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/output/java/ExtClassLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/ExtClassLoader.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/ExtClassLoader.java index 7b970bb2..9d2a8fd8 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/ExtClassLoader.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/ExtClassLoader.java @@ -90,7 +90,7 @@ public class ExtClassLoader extends AbstractClassLoader> implements Sta } @Override - public boolean shouldImport(String selfClassName, String className) { + public boolean shouldImport(String selfName, String className) { return false; } -- Gitee From 7a4dec3d43b68919ec6f6024bc62c58e1d6468d8 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Wed, 28 Apr 2021 17:34:22 +0800 Subject: [PATCH 074/121] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=B1=BB=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deduce/{NativeDerivator.java => NativeTypeDerivator.java} | 2 +- .../spirit/output/java/linker/AbstractNativeClassLinker.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/{NativeDerivator.java => NativeTypeDerivator.java} (97%) diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeDerivator.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeTypeDerivator.java similarity index 97% rename from spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeDerivator.java rename to spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeTypeDerivator.java index 2dc9333b..2049c508 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeDerivator.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeTypeDerivator.java @@ -13,7 +13,7 @@ import com.sum.spirit.core.clazz.utils.TypeVisiter; import com.sum.spirit.core.compile.deduce.TypeDerivator; @Component -public class NativeDerivator extends TypeDerivator { +public class NativeTypeDerivator extends TypeDerivator { @Autowired public ClassLinker linker; diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeClassLinker.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeClassLinker.java index f76a0b8d..864bc2b4 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeClassLinker.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeClassLinker.java @@ -10,7 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired; import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.output.java.ExtClassLoader; -import com.sum.spirit.output.java.deduce.NativeDerivator; +import com.sum.spirit.output.java.deduce.NativeTypeDerivator; import com.sum.spirit.output.java.deduce.NativeTypeFactory; public abstract class AbstractNativeClassLinker implements ClassLinker { @@ -20,7 +20,7 @@ public abstract class AbstractNativeClassLinker implements ClassLinker { @Autowired public NativeTypeFactory factory; @Autowired - public NativeDerivator derivator; + public NativeTypeDerivator derivator; @Override @SuppressWarnings("unchecked") -- Gitee From f165572e780558c81392b15bb6699707c8ef731e Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 29 Apr 2021 11:19:36 +0800 Subject: [PATCH 075/121] =?UTF-8?q?token=E5=B1=9E=E6=80=A7=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E7=94=A8=E6=88=B7=E8=87=AA=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/common/constants/Attribute.java | 12 ++++++++ .../spirit/common/enums/AttributeEnum.java | 13 --------- .../sum/spirit/core/clazz/entity/IMethod.java | 6 ++-- .../spirit/core/clazz/frame/TokenEntity.java | 4 +-- .../spirit/core/compile/AppTypeFactory.java | 4 +-- .../core/compile/DefaultElementVisiter.java | 4 +-- .../action/ElementExpressDeclarer.java | 8 +++--- .../compile/action/ElementTypeDeclarer.java | 4 +-- .../core/compile/deduce/FragmentDeducer.java | 6 ++-- .../compile/deduce/InvocationVisiter.java | 28 +++++++++---------- .../core/compile/deduce/VariableTracker.java | 8 +++--- .../element/action/AbstractTreeBuilder.java | 8 +++--- .../element/action/DefaultSemanticParser.java | 12 ++++---- .../element/action/DefaultTreeBuilder.java | 14 +++++----- .../core/element/action/SyntaxRecognizer.java | 4 +-- .../sum/spirit/core/element/entity/Token.java | 3 +- .../core/element/frame/AttributeMap.java | 28 ------------------- .../spirit/core/element/frame/Attributes.java | 26 +++++++++++++++++ .../spirit/core/element/frame/Semantic.java | 5 ++-- .../spirit/core/element/utils/StmtFormat.java | 6 ++-- .../output/java/action/StatementAction.java | 12 ++++---- .../java/action/StringEqualsAction.java | 6 ++-- .../output/java/action/StringLogicAction.java | 10 +++---- .../spirit/output/java/utils/TreeUtils.java | 6 ++-- 24 files changed, 116 insertions(+), 121 deletions(-) create mode 100644 spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java delete mode 100644 spirit-common/src/main/java/com/sum/spirit/common/enums/AttributeEnum.java delete mode 100644 spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/AttributeMap.java create mode 100644 spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Attributes.java diff --git a/spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java b/spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java new file mode 100644 index 00000000..3e635d55 --- /dev/null +++ b/spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java @@ -0,0 +1,12 @@ +package com.sum.spirit.common.constants; + +public class Attribute { + public static final String SIMPLE_NAME = "SIMPLE_NAME"; // 类名 + public static final String MEMBER_NAME = "MEMBER_NAME"; // 字段名或者方法名 + public static final String OPERAND = "OPERAND"; // 操作数 + public static final String TREE_ID = "TREE_ID"; // 树节点id + public static final String TYPE = "TYPE"; // 类型 + public static final String DERIVED = "DERIVED"; // 是否声明 + public static final String POSITION = "POSITION"; // 在语句中的位置 + public static final String LENGTH = "LENGTH"; // 字符串的宽度 +} diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/AttributeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/AttributeEnum.java deleted file mode 100644 index 242d3dda..00000000 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/AttributeEnum.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.sum.spirit.common.enums; - -public enum AttributeEnum { - SIMPLE_NAME, // 类名 - MEMBER_NAME, // 字段名或者方法名 - OPERAND, // 操作数 - TREE_ID, // 树节点id - TYPE, // 类型 - DERIVED, // 是否声明 - POSITION, // 在语句中的位置 - LENGTH, // 字符串的宽度 - USER_DEFINED;// 用户自定义 -} diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IMethod.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IMethod.java index 34f08262..47d2100e 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IMethod.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IMethod.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.List; import com.google.common.base.Joiner; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.frame.MemberEntity; import com.sum.spirit.core.element.entity.Element; @@ -21,10 +21,10 @@ public class IMethod extends MemberEntity { public String getName() { Token methodToken = element.findOneTokenOf(TokenTypeEnum.TYPE_INIT, TokenTypeEnum.LOCAL_METHOD); if (methodToken.isTypeInit()) { - return methodToken.attr(AttributeEnum.SIMPLE_NAME); + return methodToken.attr(Attribute.SIMPLE_NAME); } else if (methodToken.isLocalMethod()) { - return methodToken.attr(AttributeEnum.MEMBER_NAME); + return methodToken.attr(Attribute.MEMBER_NAME); } throw new RuntimeException("Unsupported syntax!syntax:" + element.syntax); } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TokenEntity.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TokenEntity.java index 38af5575..fd8f9609 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TokenEntity.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TokenEntity.java @@ -1,6 +1,6 @@ package com.sum.spirit.core.clazz.frame; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.core.element.entity.Token; public abstract class TokenEntity extends TypeEntity { @@ -13,7 +13,7 @@ public abstract class TokenEntity extends TypeEntity { public String getName() { if (token.isAnnotation()) { - return token.attr(AttributeEnum.SIMPLE_NAME); + return token.attr(Attribute.SIMPLE_NAME); } else if (token.isVariable()) { return token.toString(); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java index 1486ac38..1cbe9348 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/AppTypeFactory.java @@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.ModifierEnum; import com.sum.spirit.common.enums.PrimitiveEnum; import com.sum.spirit.core.clazz.AbstractTypeFactory; @@ -54,7 +54,7 @@ public class AppTypeFactory extends AbstractTypeFactory { return doCreate(clazz, token); } else if (token.isAnnotation() || token.isArrayInit() || token.isTypeInit() || token.isCast()) { - return create(clazz, (String) token.attr(AttributeEnum.SIMPLE_NAME)); + return create(clazz, (String) token.attr(Attribute.SIMPLE_NAME)); } else if (token.isLiteral()) {// 1, 1.1, "xxxx" return getValueType(clazz, token); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java index a1d32017..0b84988b 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultElementVisiter.java @@ -8,7 +8,7 @@ import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; import com.sum.spirit.common.annotation.App; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.utils.SpringUtils; import com.sum.spirit.core.api.ElementAction; import com.sum.spirit.core.api.ElementVisiter; @@ -77,7 +77,7 @@ public class DefaultElementVisiter implements ElementVisiter, InitializingBean { public IVariable createVariable(Token varToken) { IVariable variable = new IVariable(varToken); - variable.setType(varToken.attr(AttributeEnum.TYPE)); + variable.setType(varToken.attr(Attribute.TYPE)); return variable; } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java index 2db2349b..869caab8 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java @@ -5,7 +5,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.annotation.App; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.core.api.ElementBuilder; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; @@ -55,9 +55,9 @@ public class ElementExpressDeclarer extends AbstractElementAction { visiter.visit(clazz, statement); type = deducer.derive(clazz, statement); // 标记类型是否经过推导而来 - varToken.setAttr(AttributeEnum.DERIVED, true); + varToken.setAttr(Attribute.DERIVED, true); } - varToken.setAttr(AttributeEnum.TYPE, type); + varToken.setAttr(Attribute.TYPE, type); } super.handle(event); } @@ -75,7 +75,7 @@ public class ElementExpressDeclarer extends AbstractElementAction { // 获取数组内部类型和泛型类型 type = type.isArray() ? derivator.toTarget(type) : type.getGenericTypes().get(0); Token varToken = element.get(1); - varToken.setAttr(AttributeEnum.TYPE, type); + varToken.setAttr(Attribute.TYPE, type); } else if (element.isFor()) {// for (i=0; i<100; i++) { Token secondToken = element.get(1); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java index 84d8ec58..9ba90b2c 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java @@ -5,7 +5,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.annotation.App; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.compile.entity.ElementEvent; @@ -38,7 +38,7 @@ public class ElementTypeDeclarer extends AbstractElementAction { } public void setTypeByTypeToken(IClass clazz, Token typeToken, Token varToken) { - varToken.setAttr(AttributeEnum.TYPE, factory.create(clazz, typeToken)); + varToken.setAttr(Attribute.TYPE, factory.create(clazz, typeToken)); } } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/FragmentDeducer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/FragmentDeducer.java index 48056d5f..0c8afc34 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/FragmentDeducer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/FragmentDeducer.java @@ -3,7 +3,7 @@ package com.sum.spirit.core.compile.deduce; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.core.api.TreeBuilder; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; @@ -34,8 +34,8 @@ public class FragmentDeducer { Token token = node.token; // 如果有类型直接返回 - if (token.attr(AttributeEnum.TYPE) != null) { - return token.attr(AttributeEnum.TYPE); + if (token.attr(Attribute.TYPE) != null) { + return token.attr(Attribute.TYPE); } // 如果是逻辑判断,或者类型判断关键字 diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java index 3a056933..246d3632 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/InvocationVisiter.java @@ -6,7 +6,7 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IClass; @@ -32,38 +32,38 @@ public class InvocationVisiter { for (int index = 0; index < stmt.size(); index++) { try { Token token = stmt.get(index); - if (token.attr(AttributeEnum.TYPE) != null) { + if (token.attr(Attribute.TYPE) != null) { continue; } List parameterTypes = token.isInvoke() ? getParameterTypes(clazz, token) : null; if (token.isType() || token.isArrayInit() || token.isTypeInit() || token.isCast() || token.isLiteral()) { - token.setAttr(AttributeEnum.TYPE, factory.create(clazz, token)); + token.setAttr(Attribute.TYPE, factory.create(clazz, token)); } else if (token.isSubexpress()) { Statement subStatement = token.getValue(); - token.setAttr(AttributeEnum.TYPE, deducer.derive(clazz, subStatement.subStmt("(", ")"))); + token.setAttr(Attribute.TYPE, deducer.derive(clazz, subStatement.subStmt("(", ")"))); } else if (token.isLocalMethod()) { - String memberName = token.attr(AttributeEnum.MEMBER_NAME); + String memberName = token.attr(Attribute.MEMBER_NAME); IType returnType = linker.visitMethod(derivator.withThisModifiers(clazz.getType()), memberName, parameterTypes); - token.setAttr(AttributeEnum.TYPE, returnType); + token.setAttr(Attribute.TYPE, returnType); } else if (token.isVisitField()) { - IType type = stmt.get(index - 1).attr(AttributeEnum.TYPE); - String memberName = token.attr(AttributeEnum.MEMBER_NAME); + IType type = stmt.get(index - 1).attr(Attribute.TYPE); + String memberName = token.attr(Attribute.MEMBER_NAME); IType returnType = linker.visitField(type, memberName); - token.setAttr(AttributeEnum.TYPE, returnType); + token.setAttr(Attribute.TYPE, returnType); } else if (token.isVisitMethod()) { - IType type = stmt.get(index - 1).attr(AttributeEnum.TYPE); - String memberName = token.attr(AttributeEnum.MEMBER_NAME); + IType type = stmt.get(index - 1).attr(Attribute.TYPE); + String memberName = token.attr(Attribute.MEMBER_NAME); IType returnType = linker.visitMethod(type, memberName, parameterTypes); - token.setAttr(AttributeEnum.TYPE, returnType); + token.setAttr(Attribute.TYPE, returnType); } else if (token.isVisitIndex()) {// what like "[0]" - IType type = stmt.get(index - 1).attr(AttributeEnum.TYPE); + IType type = stmt.get(index - 1).attr(Attribute.TYPE); type = derivator.toTarget(type);// 转换数组类型为目标类型 - token.setAttr(AttributeEnum.TYPE, type); + token.setAttr(Attribute.TYPE, type); } } catch (NoSuchFieldException | NoSuchMethodException e) { diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java index 13177a65..8b6b9a64 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/VariableTracker.java @@ -3,7 +3,7 @@ package com.sum.spirit.core.compile.deduce; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.clazz.entity.IClass; @@ -27,18 +27,18 @@ public class VariableTracker { public void visit(IClass clazz, MethodContext context, Statement statement) { StmtVisiter.visit(statement, stmt -> { stmt.forEach(token -> { - if (token.attr(AttributeEnum.TYPE) != null) { + if (token.attr(Attribute.TYPE) != null) { return; } if (token.isVariable()) {// variable String variableName = token.toString(); IType type = getVariableType(clazz, context, variableName); - token.setAttr(AttributeEnum.TYPE, type); + token.setAttr(Attribute.TYPE, type); } else if (token.isKeyword() && KeywordEnum.isKeywordVariable(token.getValue())) { String variableName = token.toString(); IType type = findTypeByKeyword(clazz, variableName); - token.setAttr(AttributeEnum.TYPE, type); + token.setAttr(Attribute.TYPE, type); } }); }); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractTreeBuilder.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractTreeBuilder.java index e1fb7885..76ee3d0b 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractTreeBuilder.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractTreeBuilder.java @@ -2,7 +2,7 @@ package com.sum.spirit.core.element.action; import java.util.List; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.core.api.TreeBuilder; import com.sum.spirit.core.element.entity.Node; import com.sum.spirit.core.element.entity.Statement; @@ -32,7 +32,7 @@ public abstract class AbstractTreeBuilder implements TreeBuilder { } public void markTreeId(String treeId, Node node) { - node.token.setAttr(AttributeEnum.TREE_ID, treeId); + node.token.setAttr(Attribute.TREE_ID, treeId); if (node.prev != null) { markTreeId(treeId + "-" + "0", node.prev); } @@ -50,12 +50,12 @@ public abstract class AbstractTreeBuilder implements TreeBuilder { List tokens = StmtFormat.format(statement); for (int i = 0; i < tokens.size(); i++) { Token token = tokens.get(i); - token.setAttr(AttributeEnum.POSITION, position); + token.setAttr(Attribute.POSITION, position); if (token.canSplit()) { markPositionAndLength(position, token.getValue()); } int length = token.toString().length(); - token.setAttr(AttributeEnum.LENGTH, length); + token.setAttr(Attribute.LENGTH, length); position += length; } } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java index 253fc042..98f09289 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java @@ -5,7 +5,7 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.api.Lexer; import com.sum.spirit.core.element.entity.Statement; @@ -104,19 +104,19 @@ public class DefaultSemanticParser extends AbstractSemanticParser { public void setTokenAttributes(String word, Token token) { if (token.isAnnotation()) { - token.setAttr(AttributeEnum.SIMPLE_NAME, getAnnotationName(word)); + token.setAttr(Attribute.SIMPLE_NAME, getAnnotationName(word)); } else if (token.isArrayInit()) { - token.setAttr(AttributeEnum.SIMPLE_NAME, getPrefix(word) + "[]"); + token.setAttr(Attribute.SIMPLE_NAME, getPrefix(word) + "[]"); } else if (token.isTypeInit()) { - token.setAttr(AttributeEnum.SIMPLE_NAME, getPrefix(word)); + token.setAttr(Attribute.SIMPLE_NAME, getPrefix(word)); } else if (token.isCast()) { - token.setAttr(AttributeEnum.SIMPLE_NAME, getCastType(word)); + token.setAttr(Attribute.SIMPLE_NAME, getCastType(word)); } else if (token.isAccess()) { - token.setAttr(AttributeEnum.MEMBER_NAME, getPrefix(word)); + token.setAttr(Attribute.MEMBER_NAME, getPrefix(word)); } } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java index 9cc4b48d..4622ae99 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java @@ -9,7 +9,7 @@ import java.util.stream.Collectors; import org.springframework.stereotype.Component; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.SymbolEnum.OperandEnum; import com.sum.spirit.common.utils.Lists; @@ -72,7 +72,7 @@ public class DefaultTreeBuilder extends AbstractTreeBuilder { if (priority > 0) { queue.add(new PriorityNode(priority, index)); - currentToken.setAttr(AttributeEnum.OPERAND, operand); + currentToken.setAttr(Attribute.OPERAND, operand); } } return queue; @@ -86,7 +86,7 @@ public class DefaultTreeBuilder extends AbstractTreeBuilder { Token currentToken = node.token; resetOperandIfMultiple(nodes, index, currentToken);// 如果是多义的操作符,则进行判断后,确定真正的操作数 - OperandEnum operandEnum = currentToken.attr(AttributeEnum.OPERAND); + OperandEnum operandEnum = currentToken.attr(Attribute.OPERAND); if (operandEnum == OperandEnum.LEFT) { Node lastNode = Lists.findOne(nodes, index - 1, -1, Objects::nonNull); node.prev = lastNode; @@ -114,19 +114,19 @@ public class DefaultTreeBuilder extends AbstractTreeBuilder { } public void resetOperandIfMultiple(List nodes, int index, Token currentToken) { - OperandEnum operandEnum = currentToken.attr(AttributeEnum.OPERAND); + OperandEnum operandEnum = currentToken.attr(Attribute.OPERAND); if (operandEnum == OperandEnum.MULTIPLE) { Node lastNode = Lists.findOne(nodes, index - 1, -1, Objects::nonNull); String value = currentToken.toString(); if (SymbolEnum.SUBTRACT.value.equals(value)) {// 100 + (-10) // var = -1 if (lastNode != null) { if (lastNode.isMounted() || (lastNode.token.isNumber() || lastNode.token.isVariable())) { - currentToken.setAttr(AttributeEnum.OPERAND, OperandEnum.BINARY); + currentToken.setAttr(Attribute.OPERAND, OperandEnum.BINARY); } else { - currentToken.setAttr(AttributeEnum.OPERAND, OperandEnum.RIGHT); + currentToken.setAttr(Attribute.OPERAND, OperandEnum.RIGHT); } } else { - currentToken.setAttr(AttributeEnum.OPERAND, OperandEnum.RIGHT); + currentToken.setAttr(Attribute.OPERAND, OperandEnum.RIGHT); } } } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java index b9d88a15..90d83a6c 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java @@ -5,7 +5,7 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.SyntaxEnum; @@ -98,7 +98,7 @@ public class SyntaxRecognizer { } // SUPER / THIS if (firstToken.isLocalMethod()) { - String memberName = firstToken.attr(AttributeEnum.MEMBER_NAME); + String memberName = firstToken.attr(Attribute.MEMBER_NAME); if (KeywordEnum.SUPER.value.equals(memberName)) { return SyntaxEnum.SUPER; diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Token.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Token.java index 6eb20575..b5df7203 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Token.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Token.java @@ -3,7 +3,6 @@ package com.sum.spirit.core.element.entity; import java.util.HashMap; import java.util.Map; -import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.element.frame.Semantic; @@ -20,7 +19,7 @@ public class Token extends Semantic { this.value = value; } - public Token(TokenTypeEnum tokenType, Object value, Map attributes) { + public Token(TokenTypeEnum tokenType, Object value, Map attributes) { super(tokenType, attributes); this.value = value; } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/AttributeMap.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/AttributeMap.java deleted file mode 100644 index 68c97285..00000000 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/AttributeMap.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.sum.spirit.core.element.frame; - -import java.util.Map; - -import com.sum.spirit.common.enums.AttributeEnum; - -public abstract class AttributeMap { - - public Map attributes; - - public AttributeMap(Map attributes) { - this.attributes = attributes; - } - - @SuppressWarnings("unchecked") - public T attr(AttributeEnum attributeEnum) { - return (T) attributes.get(attributeEnum); - } - - public boolean attr(AttributeEnum attributeEnum, boolean defaultValue) { - return (boolean) attributes.getOrDefault(attributeEnum, defaultValue); - } - - public void setAttr(AttributeEnum attributeEnum, Object value) { - attributes.put(attributeEnum, value); - } - -} diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Attributes.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Attributes.java new file mode 100644 index 00000000..121cd8a6 --- /dev/null +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Attributes.java @@ -0,0 +1,26 @@ +package com.sum.spirit.core.element.frame; + +import java.util.Map; + +public abstract class Attributes { + + public Map attributes; + + public Attributes(Map attributes) { + this.attributes = attributes; + } + + @SuppressWarnings("unchecked") + public T attr(String attribute) { + return (T) attributes.get(attribute); + } + + public boolean attr(String attribute, boolean defaultValue) { + return (boolean) attributes.getOrDefault(attribute, defaultValue); + } + + public void setAttr(String attribute, Object value) { + attributes.put(attribute, value); + } + +} diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java index fbc91617..f0d3fef2 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Semantic.java @@ -2,16 +2,15 @@ package com.sum.spirit.core.element.frame; import java.util.Map; -import com.sum.spirit.common.enums.AttributeEnum; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.TokenTypeEnum; -public abstract class Semantic extends AttributeMap { +public abstract class Semantic extends Attributes { public TokenTypeEnum tokenType; - public Semantic(TokenTypeEnum tokenType, Map attributes) { + public Semantic(TokenTypeEnum tokenType, Map attributes) { super(attributes); this.tokenType = tokenType; } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java index 6f30d590..2d5f1f48 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/utils/StmtFormat.java @@ -2,7 +2,7 @@ package com.sum.spirit.core.element.utils; import java.util.List; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.common.enums.SymbolEnum.OperandEnum; import com.sum.spirit.core.element.entity.Statement; @@ -43,7 +43,7 @@ public class StmtFormat { return true; } else if ("-".equals(lastToken.toString())) { - OperandEnum operandEnum = lastToken.attr(AttributeEnum.OPERAND); + OperandEnum operandEnum = lastToken.attr(Attribute.OPERAND); if (operandEnum == OperandEnum.RIGHT) { tokens.remove(index); return true; @@ -67,7 +67,7 @@ public class StmtFormat { public static void dealNextToken(List tokens, int index, Token lastToken, Token nextToken) { if (nextToken.isOperator()) { if ("++".equals(nextToken.toString()) || "--".equals(nextToken.toString())) { - OperandEnum operandEnum = nextToken.attr(AttributeEnum.OPERAND); + OperandEnum operandEnum = nextToken.attr(Attribute.OPERAND); if (operandEnum == OperandEnum.LEFT) { tokens.remove(index); return; diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java index c9d5d836..731f7f26 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StatementAction.java @@ -9,7 +9,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.annotation.Native; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.entity.IClass; @@ -56,9 +56,9 @@ public class StatementAction extends AbstractElementAction { Statement statement = secondToken.getValue(); Token token = statement.get(1); if (!token.isType() && token.isVariable()) { - boolean derived = token.attr(AttributeEnum.DERIVED, false); + boolean derived = token.attr(Attribute.DERIVED, false); if (derived) { - IType type = token.attr(AttributeEnum.TYPE); + IType type = token.attr(Attribute.TYPE); statement.add(1, new Token(TokenTypeEnum.TYPE, importer.getFinalName(clazz, type))); } } @@ -66,15 +66,15 @@ public class StatementAction extends AbstractElementAction { } else if (element.isForIn()) {// for item in list { Token item = element.get(1); - IType type = item.attr(AttributeEnum.TYPE); + IType type = item.attr(Attribute.TYPE); Statement statement = element.subStmt(3, element.size() - 1); String text = String.format("for (%s %s : %s) {", importer.getFinalName(clazz, type), item, statement); element.replaceTokens(0, element.size(), new Token(TokenTypeEnum.CUSTOM_EXPRESS, text)); } else if (element.isAssign()) {// var = list.get(0) Token token = element.get(0); - boolean derived = token.attr(AttributeEnum.DERIVED, false); - IType type = token.attr(AttributeEnum.TYPE); + boolean derived = token.attr(Attribute.DERIVED, false); + IType type = token.attr(Attribute.TYPE); if (token.isVariable() && derived) { element.add(0, new Token(TokenTypeEnum.TYPE, importer.getFinalName(clazz, type))); } diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java index ba109123..0248e16b 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java @@ -8,7 +8,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.annotation.Native; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; @@ -47,8 +47,8 @@ public class StringEqualsAction extends AbstractTreeElementAction { String format = currentToken.isEquals() ? FORMAT : "!" + FORMAT; String text = String.format(format, prevStatement, nextStatement); Token expressToken = new Token(TokenTypeEnum.CUSTOM_EXPRESS, text); - expressToken.setAttr(AttributeEnum.TYPE, StaticTypes.BOOLEAN); - expressToken.setAttr(AttributeEnum.TREE_ID, currentToken.attr(AttributeEnum.TREE_ID)); + expressToken.setAttr(Attribute.TYPE, StaticTypes.BOOLEAN); + expressToken.setAttr(Attribute.TREE_ID, currentToken.attr(Attribute.TREE_ID)); statement.replaceTokens(start, end, expressToken); clazz.addImport(StringUtils.class.getName()); } diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java index 5a26d496..022cdabb 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java @@ -8,7 +8,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.annotation.Native; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; @@ -49,8 +49,8 @@ public class StringLogicAction extends AbstractTreeElementAction { if (TypeUtils.isString(prevType)) { String text = String.format(FORMAT, prevStatement); Token expressToken = new Token(TokenTypeEnum.CUSTOM_EXPRESS, text); - expressToken.setAttr(AttributeEnum.TYPE, StaticTypes.BOOLEAN); - expressToken.setAttr(AttributeEnum.TREE_ID, currentToken.attr(AttributeEnum.TREE_ID) + "-0"); + expressToken.setAttr(Attribute.TYPE, StaticTypes.BOOLEAN); + expressToken.setAttr(Attribute.TREE_ID, currentToken.attr(Attribute.TREE_ID) + "-0"); statement.replaceTokens(start, index, expressToken); clazz.addImport(StringUtils.class.getName()); } @@ -64,8 +64,8 @@ public class StringLogicAction extends AbstractTreeElementAction { if (TypeUtils.isString(nextType)) { String text = String.format(FORMAT, nextStatement); Token expressToken = new Token(TokenTypeEnum.CUSTOM_EXPRESS, text); - expressToken.setAttr(AttributeEnum.TYPE, StaticTypes.BOOLEAN); - expressToken.setAttr(AttributeEnum.TREE_ID, currentToken.attr(AttributeEnum.TREE_ID) + "-1"); + expressToken.setAttr(Attribute.TYPE, StaticTypes.BOOLEAN); + expressToken.setAttr(Attribute.TREE_ID, currentToken.attr(Attribute.TREE_ID) + "-1"); statement.replaceTokens(index + 1, end, expressToken); clazz.addImport(StringUtils.class.getName()); } diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/utils/TreeUtils.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/utils/TreeUtils.java index 9f9d7af9..cb9a3433 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/utils/TreeUtils.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/utils/TreeUtils.java @@ -1,15 +1,15 @@ package com.sum.spirit.output.java.utils; -import com.sum.spirit.common.enums.AttributeEnum; +import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.core.element.entity.Statement; public class TreeUtils { public static int findIndex(Statement statement, int index, int step) { int finalIndex = -1; - String treeId = statement.get(index).attr(AttributeEnum.TREE_ID); + String treeId = statement.get(index).attr(Attribute.TREE_ID); for (int idx = index + step; idx >= 0 && idx < statement.size(); idx += step) { - String nextTreeId = statement.get(idx).attr(AttributeEnum.TREE_ID); + String nextTreeId = statement.get(idx).attr(Attribute.TREE_ID); if (nextTreeId != null && nextTreeId.startsWith(treeId)) { finalIndex = idx; } -- Gitee From eee7d3f67d6eb2bad7428d37848650b6ecdf97ce Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 29 Apr 2021 11:23:16 +0800 Subject: [PATCH 076/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/common/constants/Attribute.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java b/spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java index 3e635d55..e34e0691 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java @@ -3,10 +3,13 @@ package com.sum.spirit.common.constants; public class Attribute { public static final String SIMPLE_NAME = "SIMPLE_NAME"; // 类名 public static final String MEMBER_NAME = "MEMBER_NAME"; // 字段名或者方法名 + public static final String OPERAND = "OPERAND"; // 操作数 public static final String TREE_ID = "TREE_ID"; // 树节点id - public static final String TYPE = "TYPE"; // 类型 - public static final String DERIVED = "DERIVED"; // 是否声明 + public static final String POSITION = "POSITION"; // 在语句中的位置 public static final String LENGTH = "LENGTH"; // 字符串的宽度 + + public static final String TYPE = "TYPE"; // 类型 + public static final String DERIVED = "DERIVED"; // 是否声明 } -- Gitee From e019225b62a3b8975c0838d23872f129eac85267 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 29 Apr 2021 11:24:00 +0800 Subject: [PATCH 077/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constants/{Constants.java => AppConfig.java} | 2 +- .../java/com/sum/spirit/common/utils/ConfigUtils.java | 10 +++++----- .../sum/spirit/core/element/DefaultDocumentReader.java | 4 ++-- .../sum/spirit/starter/kit/service/MethodService.java | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) rename spirit-common/src/main/java/com/sum/spirit/common/constants/{Constants.java => AppConfig.java} (95%) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/constants/Constants.java b/spirit-common/src/main/java/com/sum/spirit/common/constants/AppConfig.java similarity index 95% rename from spirit-common/src/main/java/com/sum/spirit/common/constants/Constants.java rename to spirit-common/src/main/java/com/sum/spirit/common/constants/AppConfig.java index af44dc76..21c4d896 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/constants/Constants.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/constants/AppConfig.java @@ -1,6 +1,6 @@ package com.sum.spirit.common.constants; -public class Constants { +public class AppConfig { public static final String DEFAULT_CHARSET = "UTF-8"; diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/ConfigUtils.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/ConfigUtils.java index 60ef713c..74b671c2 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/ConfigUtils.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/ConfigUtils.java @@ -4,7 +4,7 @@ import org.springframework.context.EnvironmentAware; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; -import com.sum.spirit.common.constants.Constants; +import com.sum.spirit.common.constants.AppConfig; @Component public class ConfigUtils implements EnvironmentAware { @@ -41,19 +41,19 @@ public class ConfigUtils implements EnvironmentAware { } public static String getInputPath() { - return ConfigUtils.getProperty(Constants.INPUT_ARG_KEY); + return ConfigUtils.getProperty(AppConfig.INPUT_ARG_KEY); } public static String getOutputPath() { - return ConfigUtils.getProperty(Constants.OUTPUT_ARG_KEY); + return ConfigUtils.getProperty(AppConfig.OUTPUT_ARG_KEY); } public static String getFileExtension() { - return ConfigUtils.getProperty(Constants.FILENAME_EXTENSION_KEY, Constants.DEFAULT_FILENAME_EXTENSION); + return ConfigUtils.getProperty(AppConfig.FILENAME_EXTENSION_KEY, AppConfig.DEFAULT_FILENAME_EXTENSION); } public static boolean isDebug() { - return ConfigUtils.getProperty(Constants.DEBUG_KEY, Constants.DEFAULT_DEBUG); + return ConfigUtils.getProperty(AppConfig.DEBUG_KEY, AppConfig.DEFAULT_DEBUG); } } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java index 71c27caa..d95191b6 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java @@ -8,7 +8,7 @@ import java.util.Stack; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.sum.spirit.common.constants.Constants; +import com.sum.spirit.common.constants.AppConfig; import com.sum.spirit.common.utils.ConfigUtils; import com.sum.spirit.common.utils.LineUtils; import com.sum.spirit.common.utils.Lists; @@ -31,7 +31,7 @@ public class DefaultDocumentReader implements DocumentReader { @Override public Document read(String fileName, InputStream input) { Document document = new Document(fileName); - List lines = IoUtil.readLines(input, Constants.DEFAULT_CHARSET, new ArrayList()); + List lines = IoUtil.readLines(input, AppConfig.DEFAULT_CHARSET, new ArrayList()); doReadLines(document, lines); if (ConfigUtils.isDebug()) { document.debug(); diff --git a/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/service/MethodService.java b/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/service/MethodService.java index fcfd2798..7dbf04df 100644 --- a/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/service/MethodService.java +++ b/spirit-starter/spirit-starter-kit/src/main/java/com/sum/spirit/starter/kit/service/MethodService.java @@ -10,7 +10,7 @@ import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.sum.spirit.common.constants.Constants; +import com.sum.spirit.common.constants.AppConfig; import com.sum.spirit.common.utils.LineUtils; import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.clazz.entity.IClass; @@ -43,7 +43,7 @@ public class MethodService { // 根据文件名,获取className String className = loader.getName(filePath); // 找到对应class,并找到印记,获取推导出的类型,并返回所有该类型的方法信息 - IClass clazz = loader.loadClass(className, IoUtil.toStream(content, Constants.DEFAULT_CHARSET)); + IClass clazz = loader.loadClass(className, IoUtil.toStream(content, AppConfig.DEFAULT_CHARSET)); IType type = selector.findElementAndGetType(clazz, lineNumber); Object clazzObj = linker.toClass(type); -- Gitee From 7648b3676201eb43ab0f3b962d4c2537df01d8f3 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 29 Apr 2021 11:24:37 +0800 Subject: [PATCH 078/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/common/constants/Attribute.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java b/spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java index e34e0691..f1fb1423 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/constants/Attribute.java @@ -1,6 +1,7 @@ package com.sum.spirit.common.constants; public class Attribute { + public static final String SIMPLE_NAME = "SIMPLE_NAME"; // 类名 public static final String MEMBER_NAME = "MEMBER_NAME"; // 字段名或者方法名 @@ -12,4 +13,5 @@ public class Attribute { public static final String TYPE = "TYPE"; // 类型 public static final String DERIVED = "DERIVED"; // 是否声明 + } -- Gitee From b45529be1ef0bca6414a6e3d40bc85495814aadc Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 29 Apr 2021 11:26:36 +0800 Subject: [PATCH 079/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/common/enums/SyntaxEnum.java | 8 -------- .../java/com/sum/spirit/common/enums/TokenTypeEnum.java | 8 -------- 2 files changed, 16 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java index 3cc2e359..85d5d357 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java @@ -1,13 +1,5 @@ package com.sum.spirit.common.enums; -//import com.sum.spirit.example.Animal -//@Animal -//class Horse { -// name = "Jessie" -// func call() { -// return "I am Jessie!" -// } -//} public enum SyntaxEnum { IMPORT, // import com.sum.spirit.example.Animal ANNOTATION, // @Animal diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java index 07f8a4da..a2d294b7 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/TokenTypeEnum.java @@ -1,13 +1,5 @@ package com.sum.spirit.common.enums; -//import com.sum.spirit.example.Animal -//@Animal -//class Horse { -// name = "Jessie" -// func call() { -// return "I am Jessie!" -// } -//} public enum TokenTypeEnum { PATH, // com.sum.spirit.example.Animal ANNOTATION, // @Animal -- Gitee From bf88b36dee3379fe0edcfe53564a7b0a7a83074f Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 29 Apr 2021 11:28:14 +0800 Subject: [PATCH 080/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java | 2 +- .../com/sum/spirit/core/element/DefaultDocumentReader.java | 2 +- .../com/sum/spirit/core/element/action/SyntaxRecognizer.java | 2 +- .../java/com/sum/spirit/core/element/frame/Syntactic.java | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java index 85d5d357..7524583a 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/SyntaxEnum.java @@ -14,7 +14,7 @@ public enum SyntaxEnum { DECLARE_FUNC, // String call() { FUNC, // func call() { FIELD_ASSIGN, // horse.name = "Jessie" - OBJECT_ASSIGN, // horse = { + STRUCT_ASSIGN, // horse = { INVOKE, // horse.call() RETURN, // return "I am Jessie!" IF, // if name == "Jessie" { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java index d95191b6..b5c0c7a0 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java @@ -74,7 +74,7 @@ public class DefaultDocumentReader implements DocumentReader { } public boolean mergeLinesIfPossible(Document document, List lines, int startIndex, Element element) { - if (element.isObjectAssign()) { + if (element.isStructAssign()) { StringBuilder builder = new StringBuilder(lines.get(startIndex)); for (int index = startIndex + 1; index < lines.size(); index++) { builder.append(StrUtil.removeAny(lines.get(index), "\t").trim()); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java index 90d83a6c..083d6a43 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java @@ -147,7 +147,7 @@ public class SyntaxRecognizer { Token prevToken = firstNode.prev.token; Token nextToken = firstNode.next.token; if (nextToken.isSeparator() && SymbolEnum.LEFT_CURLY_BRACKET.value.equals(nextToken.toString())) {// var = { - return SyntaxEnum.OBJECT_ASSIGN; + return SyntaxEnum.STRUCT_ASSIGN; } else if (prevToken.isType()) {// String text = "abc" return SyntaxEnum.DECLARE_ASSIGN; diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java index d094e8c0..891de7db 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/Syntactic.java @@ -55,8 +55,8 @@ public abstract class Syntactic extends Statement { return syntax == SyntaxEnum.ASSIGN; } - public boolean isObjectAssign() { - return syntax == SyntaxEnum.OBJECT_ASSIGN; + public boolean isStructAssign() { + return syntax == SyntaxEnum.STRUCT_ASSIGN; } public boolean isDeclareFunc() { -- Gitee From a48df5e65ac28dfb27ac45a326faa294362662a2 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 29 Apr 2021 12:59:19 +0800 Subject: [PATCH 081/121] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E4=BA=86=E5=AF=B9gua?= =?UTF-8?q?va=E7=9A=84=E5=BC=BA=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +-- .../utils/{Lists.java => ListUtils.java} | 2 +- .../main/java/com/sum/spirit/lib/Lists.java | 92 +++++++++++++++++++ .../main/java/com/sum/spirit/lib/Maps.java | 13 +++ .../core/clazz/AbstractURLClassLoader.java | 4 +- .../sum/spirit/core/clazz/entity/IClass.java | 4 +- .../core/clazz/frame/AnnotationEntity.java | 6 +- .../spirit/core/clazz/frame/ImportEntity.java | 10 +- .../core/compile/DefaultClassVisiter.java | 4 +- .../core/compile/linker/AppClassLinker.java | 4 +- .../core/element/DefaultDocumentReader.java | 4 +- .../action/AbstractSemanticParser.java | 6 +- .../element/action/DefaultTreeBuilder.java | 14 +-- .../spirit/core/element/entity/Modifiers.java | 4 +- .../core/element/frame/KeywordTokenBox.java | 6 +- .../spirit/core/element/frame/TokenBox.java | 10 +- .../lexer/action/AbstractLexerAction.java | 6 +- .../core/lexer/action/RegionAction.java | 14 +-- .../output/java/action/CommonAction.java | 6 +- .../test/java/com/sum/test/block/Block.java | 4 +- .../java/com/sum/test/subexpress/Express.java | 4 +- .../test/java/com/sum/test/syntax/Syntax.java | 4 +- .../src/test/java/com/sum/test/type/Type.java | 14 +-- spirit/target/com/sum/spirit/lib/Lists.java | 92 +++++++++++++++++++ spirit/target/com/sum/spirit/lib/Maps.java | 13 +++ 25 files changed, 279 insertions(+), 75 deletions(-) rename spirit-common/src/main/java/com/sum/spirit/common/utils/{Lists.java => ListUtils.java} (99%) create mode 100644 spirit-common/src/main/java/com/sum/spirit/lib/Lists.java create mode 100644 spirit/target/com/sum/spirit/lib/Lists.java diff --git a/README.md b/README.md index e0ae7173..d3cf6123 100644 --- a/README.md +++ b/README.md @@ -41,11 +41,11 @@ public class Main { 生成的代码可以直接拷贝到maven项目中,但项目中必须包含以下依赖。 ``` - + - com.google.guava - guava - ${guava.version} + org.slf4j + slf4j-api + ${slf4j.version} @@ -53,11 +53,5 @@ public class Main { commons-lang3 ${lang3.version} - - - org.slf4j - slf4j-api - ${slf4j.version} - ``` diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java similarity index 99% rename from spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java rename to spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java index 3fffd494..f123429c 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/Lists.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java @@ -6,7 +6,7 @@ import java.util.List; import cn.hutool.core.collection.CollUtil; -public class Lists { +public class ListUtils { @SafeVarargs public static List toListNonNull(T... items) { diff --git a/spirit-common/src/main/java/com/sum/spirit/lib/Lists.java b/spirit-common/src/main/java/com/sum/spirit/lib/Lists.java new file mode 100644 index 00000000..ac3ae368 --- /dev/null +++ b/spirit-common/src/main/java/com/sum/spirit/lib/Lists.java @@ -0,0 +1,92 @@ +package com.sum.spirit.lib; + +import java.util.ArrayList; +import java.util.List; + +public class Lists { + + public static List newArrayList() { + return new ArrayList<>(); + } + + public static List of() { + return newArrayList(); + } + + public static List of(E e1) { + List list = of(); + list.add(e1); + return list; + } + + public static List of(E e1, E e2) { + List list = of(); + list.add(e1); + list.add(e2); + return list; + } + + public static List of(E e1, E e2, E e3) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + return list; + } + + public static List of(E e1, E e2, E e3, E e4) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + list.add(e4); + return list; + } + + public static List of(E e1, E e2, E e3, E e4, E e5) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + list.add(e4); + list.add(e5); + return list; + } + + public static List of(E e1, E e2, E e3, E e4, E e5, E e6) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + list.add(e4); + list.add(e5); + list.add(e6); + return list; + } + + public static List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + list.add(e4); + list.add(e5); + list.add(e6); + list.add(e7); + return list; + } + + public static List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + list.add(e4); + list.add(e5); + list.add(e6); + list.add(e7); + list.add(e8); + return list; + } + +} diff --git a/spirit-common/src/main/java/com/sum/spirit/lib/Maps.java b/spirit-common/src/main/java/com/sum/spirit/lib/Maps.java index 0681d8bf..2d1599a6 100644 --- a/spirit-common/src/main/java/com/sum/spirit/lib/Maps.java +++ b/spirit-common/src/main/java/com/sum/spirit/lib/Maps.java @@ -76,4 +76,17 @@ public class Maps { return map; } + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) { + Map map = of(); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + map.put(k6, v6); + map.put(k7, v7); + map.put(k8, v8); + return map; + } + } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractURLClassLoader.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractURLClassLoader.java index 88d47171..bc6ef8e1 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractURLClassLoader.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractURLClassLoader.java @@ -16,7 +16,7 @@ import org.springframework.beans.factory.InitializingBean; import com.sum.spirit.common.utils.ConfigUtils; import com.sum.spirit.common.utils.URLFileUtils; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.clazz.entity.IClass; import cn.hutool.core.lang.Assert; @@ -87,7 +87,7 @@ public abstract class AbstractURLClassLoader extends AbstractClassLoader @Override public String findClassName(String simpleName) { - return Lists.findOne(classes.keySet(), className -> className.endsWith("." + simpleName)); + return ListUtils.findOne(classes.keySet(), className -> className.endsWith("." + simpleName)); } public void clear() { diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java index 04b0072d..120c7804 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/IClass.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.stream.Collectors; import com.sum.spirit.common.enums.KeywordEnum; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.clazz.frame.ImportEntity; import com.sum.spirit.core.clazz.utils.TypeUtils; import com.sum.spirit.core.element.entity.Element; @@ -86,7 +86,7 @@ public class IClass extends ImportEntity { } public IField getField(String fieldName) { - return Lists.findOne(fields, field -> field.getName().equals(fieldName)); + return ListUtils.findOne(fields, field -> field.getName().equals(fieldName)); } public List getMethods(String methodName) { diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/AnnotationEntity.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/AnnotationEntity.java index c5b216d9..5fbbcc93 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/AnnotationEntity.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/AnnotationEntity.java @@ -3,7 +3,7 @@ package com.sum.spirit.core.clazz.frame; import java.util.ArrayList; import java.util.List; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.element.entity.Element; @@ -17,11 +17,11 @@ public abstract class AnnotationEntity extends ElementEntity { } public IAnnotation getAnnotation(String className) { - return Lists.findOne(annotations, annotation -> annotation.getType().getClassName().equals(className)); + return ListUtils.findOne(annotations, annotation -> annotation.getType().getClassName().equals(className)); } public IAnnotation removeAnnotation(String className) { - return Lists.remove(annotations, annotation -> annotation.getType().getClassName().equals(className)); + return ListUtils.remove(annotations, annotation -> annotation.getType().getClassName().equals(className)); } } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java index 152bf910..971f0eff 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.stream.Collectors; import com.sum.spirit.common.enums.PrimitiveEnum; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.clazz.entity.Import; import com.sum.spirit.core.clazz.utils.TypeUtils; @@ -31,11 +31,11 @@ public abstract class ImportEntity extends ContextEntity { } public Import findImport(String className) { - return Lists.findOne(imports, import0 -> import0.matchClassName(className)); + return ListUtils.findOne(imports, import0 -> import0.matchClassName(className)); } public Import findImportByLastName(String simpleName) { - return Lists.findOne(imports, import0 -> import0.matchSimpleName(simpleName)); + return ListUtils.findOne(imports, import0 -> import0.matchSimpleName(simpleName)); } public String findClassName(String simpleName) { @@ -98,11 +98,11 @@ public abstract class ImportEntity extends ContextEntity { } public String findClassNameByLoader(String simpleName) { - return Lists.collectOne(context.getImportSelectors(), importSelector -> importSelector.findClassName(simpleName)); + return ListUtils.collectOne(context.getImportSelectors(), importSelector -> importSelector.findClassName(simpleName)); } public boolean shouldImport(String selfName, String className) { - Boolean flag = Lists.collectOne(context.getImportSelectors(), importSelector -> importSelector.isHandle(className), + Boolean flag = ListUtils.collectOne(context.getImportSelectors(), importSelector -> importSelector.isHandle(className), importSelector -> importSelector.shouldImport(selfName, className)); return flag == null ? true : flag; } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java index ea65c2cc..a20f9eae 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/DefaultClassVisiter.java @@ -6,7 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.TokenTypeEnum; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.common.utils.ObjectUtils; import com.sum.spirit.core.api.ClassVisiter; import com.sum.spirit.core.api.ElementBuilder; @@ -71,7 +71,7 @@ public class DefaultClassVisiter implements ClassVisiter { Statement statement = methodToken.getValue(); List statements = statement.subStmt("(", ")").splitStmt(","); for (Statement parameterStmt : statements) { - List annotations = Lists.filterStoppable(parameterStmt, token -> token.isAnnotation(), token -> new IAnnotation(token)); + List annotations = ListUtils.filterStoppable(parameterStmt, token -> token.isAnnotation(), token -> new IAnnotation(token)); IParameter parameter = new IParameter(annotations, builder.rebuild(parameterStmt)); parameter.setType(factory.create(clazz, parameterStmt.get(0))); method.parameters.add(parameter); diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java index 94315602..300f58a7 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java @@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.api.ClassVisiter; import com.sum.spirit.core.clazz.entity.IClass; @@ -74,7 +74,7 @@ public class AppClassLinker implements ClassLinker { public IType visitMethod(IType type, String methodName, List parameterTypes) throws NoSuchMethodException { IClass clazz = toClass(type); List methods = clazz.getMethods(methodName); - IMethod method = Lists.findOne(methods, eachMethod -> matches(type, eachMethod, parameterTypes)); + IMethod method = ListUtils.findOne(methods, eachMethod -> matches(type, eachMethod, parameterTypes)); if (method != null) { return derivator.populate(type, visiter.visitMember(clazz, method)); } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java index b5c0c7a0..35bdb2a8 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java @@ -11,7 +11,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.constants.AppConfig; import com.sum.spirit.common.utils.ConfigUtils; import com.sum.spirit.common.utils.LineUtils; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.api.DocumentReader; import com.sum.spirit.core.api.ElementBuilder; import com.sum.spirit.core.element.entity.Document; @@ -80,7 +80,7 @@ public class DefaultDocumentReader implements DocumentReader { builder.append(StrUtil.removeAny(lines.get(index), "\t").trim()); int end = LineUtils.findEndIndex(builder, 0, '{', '}'); if (end != -1) { - Lists.remove(lines, startIndex, index + 1); + ListUtils.remove(lines, startIndex, index + 1); lines.add(startIndex, builder.toString()); return true; } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index 3c10c7f6..0c68060b 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -8,7 +8,7 @@ import com.sum.spirit.common.enums.LiteralEnum; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.common.enums.TypeEnum; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.api.SemanticParser; import com.sum.spirit.core.element.entity.Token; @@ -29,12 +29,12 @@ public abstract class AbstractSemanticParser implements SemanticParser { @Override public List getTokens(List words) { - return Lists.collectAll(words, word -> true, word -> getToken(word)); + return ListUtils.collectAll(words, word -> true, word -> getToken(word)); } @Override public List getTokensInsideType(List words) { - return Lists.collectAll(words, word -> true, word -> getTokenInsideType(word)); + return ListUtils.collectAll(words, word -> true, word -> getTokenInsideType(word)); } @Override diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java index 4622ae99..b65b32b4 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java @@ -12,7 +12,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.SymbolEnum.OperandEnum; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.element.entity.Node; import com.sum.spirit.core.element.entity.SyntaxTree; import com.sum.spirit.core.element.entity.Token; @@ -25,7 +25,7 @@ public class DefaultTreeBuilder extends AbstractTreeBuilder { @Override public List buildNodes(List tokens) { final List nodes = new ArrayList<>(); - Lists.visit(tokens, (index, token) -> { + ListUtils.visit(tokens, (index, token) -> { if (token.canSplit()) {// 嵌套语法树 SyntaxTree syntaxTree = buildTree(token.getValue()); token = new Token(token.tokenType, syntaxTree, token.attributes); @@ -88,21 +88,21 @@ public class DefaultTreeBuilder extends AbstractTreeBuilder { OperandEnum operandEnum = currentToken.attr(Attribute.OPERAND); if (operandEnum == OperandEnum.LEFT) { - Node lastNode = Lists.findOne(nodes, index - 1, -1, Objects::nonNull); + Node lastNode = ListUtils.findOne(nodes, index - 1, -1, Objects::nonNull); node.prev = lastNode; nodes.set(lastNode.index, null); } else if (operandEnum == OperandEnum.RIGHT) { - Node nextNode = Lists.findOne(nodes, index + 1, nodes.size(), Objects::nonNull); + Node nextNode = ListUtils.findOne(nodes, index + 1, nodes.size(), Objects::nonNull); node.next = nextNode; nodes.set(nextNode.index, null); } else if (operandEnum == OperandEnum.BINARY) { - Node lastNode = Lists.findOne(nodes, index - 1, -1, Objects::nonNull); + Node lastNode = ListUtils.findOne(nodes, index - 1, -1, Objects::nonNull); node.prev = lastNode; nodes.set(lastNode.index, null); - Node nextNode = Lists.findOne(nodes, index + 1, nodes.size(), Objects::nonNull); + Node nextNode = ListUtils.findOne(nodes, index + 1, nodes.size(), Objects::nonNull); node.next = nextNode; nodes.set(nextNode.index, null); @@ -116,7 +116,7 @@ public class DefaultTreeBuilder extends AbstractTreeBuilder { public void resetOperandIfMultiple(List nodes, int index, Token currentToken) { OperandEnum operandEnum = currentToken.attr(Attribute.OPERAND); if (operandEnum == OperandEnum.MULTIPLE) { - Node lastNode = Lists.findOne(nodes, index - 1, -1, Objects::nonNull); + Node lastNode = ListUtils.findOne(nodes, index - 1, -1, Objects::nonNull); String value = currentToken.toString(); if (SymbolEnum.SUBTRACT.value.equals(value)) {// 100 + (-10) // var = -1 if (lastNode != null) { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Modifiers.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Modifiers.java index 1018f6b6..be2fd3e9 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Modifiers.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/Modifiers.java @@ -3,13 +3,13 @@ package com.sum.spirit.core.element.entity; import java.util.List; import com.google.common.base.Joiner; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.element.frame.KeywordTokenBox; public class Modifiers extends KeywordTokenBox { public Modifiers(List tokens) { - super(Lists.filterStoppable(tokens, token -> token.isModifier())); + super(ListUtils.filterStoppable(tokens, token -> token.isModifier())); } @Override diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/KeywordTokenBox.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/KeywordTokenBox.java index b83172fa..28dba2ac 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/KeywordTokenBox.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/KeywordTokenBox.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.List; import com.sum.spirit.common.enums.TokenTypeEnum; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.element.entity.Token; import cn.hutool.core.lang.Assert; @@ -16,7 +16,7 @@ public abstract class KeywordTokenBox extends TokenBox { } public int indexOfKeyword(String keyword) { - return Lists.indexOf(this, token -> token.isKeyword() && keyword.equals(token.toString())); + return ListUtils.indexOf(this, token -> token.isKeyword() && keyword.equals(token.toString())); } public boolean containsKeyword(String keyword) { @@ -53,7 +53,7 @@ public abstract class KeywordTokenBox extends TokenBox { } public int findKeywordEnd(int index) { - int endIndex = Lists.indexOf(this, index + 1, token -> token.isKeyword() || (token.isSeparator() && !",".equals(token.toString()))); + int endIndex = ListUtils.indexOf(this, index + 1, token -> token.isKeyword() || (token.isSeparator() && !",".equals(token.toString()))); if (endIndex == -1) { return size(); } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/TokenBox.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/TokenBox.java index 11536d3a..c84629b6 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/TokenBox.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/TokenBox.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.List; import com.sum.spirit.common.enums.TokenTypeEnum; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.common.utils.Splitter; import com.sum.spirit.core.element.entity.Token; import com.sum.spirit.core.element.utils.MappableList; @@ -38,12 +38,12 @@ public class TokenBox extends MappableList { } public void replaceTokens(int fromIndex, int toIndex, Token token) { - Lists.remove(this, fromIndex, toIndex); + ListUtils.remove(this, fromIndex, toIndex); add(fromIndex, token); } public Token findOneTokenOf(TokenTypeEnum... tokenTypes) { - return Lists.findOne(this, token -> ArrayUtil.contains(tokenTypes, token.tokenType)); + return ListUtils.findOne(this, token -> ArrayUtil.contains(tokenTypes, token.tokenType)); } public boolean isSymbol(Token token) { @@ -55,11 +55,11 @@ public class TokenBox extends MappableList { } public int indexOf(String str) { - return Lists.indexOf(this, token -> isSymbol(token) && str.equals(token.toString())); + return ListUtils.indexOf(this, token -> isSymbol(token) && str.equals(token.toString())); } public int lastIndexOf(String str) { - return Lists.lastIndexOf(this, token -> isSymbol(token) && str.equals(token.toString())); + return ListUtils.lastIndexOf(this, token -> isSymbol(token) && str.equals(token.toString())); } public boolean contains(String str) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java index 93e9c3fa..0bc1b948 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java @@ -6,7 +6,7 @@ import java.util.Map; import org.apache.commons.lang3.StringUtils; import com.sum.spirit.common.utils.LineUtils; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.api.CharAction; import com.sum.spirit.core.lexer.entity.Region; @@ -25,8 +25,8 @@ public abstract class AbstractLexerAction implements CharAction { public Region mergeRegions(List regions) { Assert.notEmpty(regions, "The regions cannot be empty!"); - Region startRegion = Lists.findOneByScore(regions, region -> 0 - region.startIndex); - Region endRegion = Lists.findOneByScore(regions, region -> region.endIndex); + Region startRegion = ListUtils.findOneByScore(regions, region -> 0 - region.startIndex); + Region endRegion = ListUtils.findOneByScore(regions, region -> region.endIndex); return new Region(startRegion.startIndex, endRegion.endIndex); } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java index dcfe2fca..61531bcf 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java @@ -6,7 +6,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.TypeEnum; -import com.sum.spirit.common.utils.Lists; +import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; import com.sum.spirit.core.lexer.entity.Region; @@ -55,20 +55,20 @@ public class RegionAction extends AbstractLexerAction { if (ch == '"') { Region region = findRegion(builder, context.index, '"', '"'); - pushStack(event, Lists.toListNonNull(region), "@str"); + pushStack(event, ListUtils.toListNonNull(region), "@str"); } else if (ch == '\'') { Region region = findRegion(builder, context.index, '\'', '\''); - pushStack(event, Lists.toListNonNull(region), "@char"); + pushStack(event, ListUtils.toListNonNull(region), "@char"); } else if (ch == '{') { Region region = findRegion(builder, context.index, '{', '}'); - pushStack(event, Lists.toListNonNull(region), "@map"); + pushStack(event, ListUtils.toListNonNull(region), "@map"); } else if (ch == '(') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; Region region1 = findRegion(builder, context.index, '(', ')'); - pushStack(event, Lists.toListNonNull(region0, region1), "@invoke_like"); + pushStack(event, ListUtils.toListNonNull(region0, region1), "@invoke_like"); resetIndex(event); } else if (ch == '[') { @@ -86,14 +86,14 @@ public class RegionAction extends AbstractLexerAction { region2 = findRegion(builder, region1.endIndex + 1, '{', '}'); } } - pushStack(event, Lists.toListNonNull(region0, region1, region2), "@array_like"); + pushStack(event, ListUtils.toListNonNull(region0, region1, region2), "@array_like"); resetIndex(event); } else if (ch == '<') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; Region region1 = findRegion(builder, context.index, '<', '>'); Region region2 = isCharAt(builder, region1.endIndex, '(') ? findRegion(builder, region1.endIndex, '(', ')') : null; - pushStack(event, Lists.toListNonNull(region0, region1, region2), "@generic"); + pushStack(event, ListUtils.toListNonNull(region0, region1, region2), "@generic"); resetIndex(event); } } diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java index 2810577b..9ae3e715 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java @@ -3,7 +3,6 @@ package com.sum.spirit.output.java.action; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import com.google.common.collect.Lists; import com.sum.spirit.common.annotation.Native; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.clazz.entity.IClass; @@ -12,6 +11,7 @@ import com.sum.spirit.core.compile.entity.ElementEvent; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; import com.sum.spirit.core.element.utils.StmtVisiter; +import com.sum.spirit.lib.Lists; import com.sum.spirit.lib.Maps; @Native @@ -33,9 +33,9 @@ public class CommonAction extends AbstractElementAction { Statement subStatement = token.getValue(); subStatement.add(0, new Token(TokenTypeEnum.KEYWORD, "new")); - } else if (token.isList()) {// ["value"] => Lists.newArrayList("value"); + } else if (token.isList()) {// ["value"] => Lists.of("value"); Statement subStatement = token.getValue(); - subStatement.set(0, new Token(TokenTypeEnum.CUSTOM_PREFIX, "Lists.newArrayList(")); + subStatement.set(0, new Token(TokenTypeEnum.CUSTOM_PREFIX, "Lists.of(")); subStatement.set(subStatement.size() - 1, new Token(TokenTypeEnum.CUSTOM_SUFFIX, ")")); clazz.addImport(Lists.class.getName()); diff --git a/spirit-test/src/test/java/com/sum/test/block/Block.java b/spirit-test/src/test/java/com/sum/test/block/Block.java index 5459b106..d0a5b56d 100644 --- a/spirit-test/src/test/java/com/sum/test/block/Block.java +++ b/spirit-test/src/test/java/com/sum/test/block/Block.java @@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory; import com.sum.spirit.lib.Maps; import java.util.Map; import java.util.Map.Entry; -import com.google.common.collect.Lists; +import com.sum.spirit.lib.Lists; import java.util.List; public class Block { @@ -49,7 +49,7 @@ public class Block { for (Entry entry : map.entrySet()) { logger.info("test entry!", entry.getKey()); } - List list = Lists.newArrayList("first", "second", "third"); + List list = Lists.of("first", "second", "third"); for (String str : list) { logger.info(str); break; diff --git a/spirit-test/src/test/java/com/sum/test/subexpress/Express.java b/spirit-test/src/test/java/com/sum/test/subexpress/Express.java index 7941964b..297ac594 100644 --- a/spirit-test/src/test/java/com/sum/test/subexpress/Express.java +++ b/spirit-test/src/test/java/com/sum/test/subexpress/Express.java @@ -3,7 +3,7 @@ package com.sum.test.subexpress; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.Lists; +import com.sum.spirit.lib.Lists; import java.util.List; public class Express { @@ -30,7 +30,7 @@ public class Express { public String testTree() { boolean b = (x + 1 > 0 && y < 100) && StringUtils.equals(s, "test") && s instanceof Object; logger.info("test tree", b); - List list = Lists.newArrayList("one", "two", "three"); + List list = Lists.of("one", "two", "three"); boolean b1 = ((Object) list.get(1)).toString().length() + 100 > 0; logger.info("tree", b1); String s1 = ((Object) list.get(1)).toString(); diff --git a/spirit-test/src/test/java/com/sum/test/syntax/Syntax.java b/spirit-test/src/test/java/com/sum/test/syntax/Syntax.java index 73090331..eaef0a73 100644 --- a/spirit-test/src/test/java/com/sum/test/syntax/Syntax.java +++ b/spirit-test/src/test/java/com/sum/test/syntax/Syntax.java @@ -2,7 +2,7 @@ package com.sum.test.syntax; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.Lists; +import com.sum.spirit.lib.Lists; import java.util.List; import com.sum.spirit.lib.Maps; import java.util.Map; @@ -10,7 +10,7 @@ import java.util.Map; public class Syntax { public static final Logger logger = LoggerFactory.getLogger(Syntax.class); - public List list = Lists.newArrayList("first", "second"); + public List list = Lists.of("first", "second"); public Map map = Maps.of("key", 100, "key", 100); public void testJudge() { diff --git a/spirit-test/src/test/java/com/sum/test/type/Type.java b/spirit-test/src/test/java/com/sum/test/type/Type.java index b39c71d1..f212ebe7 100644 --- a/spirit-test/src/test/java/com/sum/test/type/Type.java +++ b/spirit-test/src/test/java/com/sum/test/type/Type.java @@ -8,7 +8,7 @@ import com.sum.test.clazz.ServiceImpl; import com.sum.test.process.Main; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.Lists; +import com.sum.spirit.lib.Lists; import java.util.List; import com.sum.spirit.lib.Maps; import java.util.Map; @@ -25,11 +25,11 @@ public class Type { public int i = 100; public double d = 100.0; public String s = "string"; - public List emptyList = Lists.newArrayList(); + public List emptyList = Lists.of(); public Map emptyMap = Maps.of(); - public List list = Lists.newArrayList("first", "second", "third"); - public List list1 = Lists.newArrayList("string", 100); - public List> map = Lists.newArrayList(Maps.of("key1", 123, "key2", "123"), Maps.of("key1", 123, "key2", "123")); + public List list = Lists.of("first", "second", "third"); + public List list1 = Lists.of("string", 100); + public List> map = Lists.of(Maps.of("key1", 123, "key2", "123"), Maps.of("key1", 123, "key2", "123")); public Map map1 = Maps.of("key1", "string", "key2", 100); public boolean[] bArray = new boolean[10]; public char[] cArray = new char[10]; @@ -93,7 +93,7 @@ public class Type { GenericType generic = new GenericType(); Integer gKey = generic.get("test"); logger.info(gKey + ""); - List intsss = Lists.newArrayList(1, 123, 8987879); + List intsss = Lists.of(1, 123, 8987879); Integer integer = intsss.get(0); int numberxxx = integer.intValue(); logger.info("" + numberxxx); @@ -104,7 +104,7 @@ public class Type { logger.info(strxxxx); boolean bbxxx = getArray()[0]; logger.info("" + bbxxx); - Map objvar = Maps.of("name", "chen", "age", 18, "from", "China", "brother", Lists.newArrayList("wanhao", "chenzhe")); + Map objvar = Maps.of("name", "chen", "age", 18, "from", "China", "brother", Lists.of("wanhao", "chenzhe")); String str0 = objvar.toString(); logger.info(str0); } diff --git a/spirit/target/com/sum/spirit/lib/Lists.java b/spirit/target/com/sum/spirit/lib/Lists.java new file mode 100644 index 00000000..ac3ae368 --- /dev/null +++ b/spirit/target/com/sum/spirit/lib/Lists.java @@ -0,0 +1,92 @@ +package com.sum.spirit.lib; + +import java.util.ArrayList; +import java.util.List; + +public class Lists { + + public static List newArrayList() { + return new ArrayList<>(); + } + + public static List of() { + return newArrayList(); + } + + public static List of(E e1) { + List list = of(); + list.add(e1); + return list; + } + + public static List of(E e1, E e2) { + List list = of(); + list.add(e1); + list.add(e2); + return list; + } + + public static List of(E e1, E e2, E e3) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + return list; + } + + public static List of(E e1, E e2, E e3, E e4) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + list.add(e4); + return list; + } + + public static List of(E e1, E e2, E e3, E e4, E e5) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + list.add(e4); + list.add(e5); + return list; + } + + public static List of(E e1, E e2, E e3, E e4, E e5, E e6) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + list.add(e4); + list.add(e5); + list.add(e6); + return list; + } + + public static List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + list.add(e4); + list.add(e5); + list.add(e6); + list.add(e7); + return list; + } + + public static List of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) { + List list = of(); + list.add(e1); + list.add(e2); + list.add(e3); + list.add(e4); + list.add(e5); + list.add(e6); + list.add(e7); + list.add(e8); + return list; + } + +} diff --git a/spirit/target/com/sum/spirit/lib/Maps.java b/spirit/target/com/sum/spirit/lib/Maps.java index 14eda487..aca3a4b2 100644 --- a/spirit/target/com/sum/spirit/lib/Maps.java +++ b/spirit/target/com/sum/spirit/lib/Maps.java @@ -76,4 +76,17 @@ public class Maps { return map; } + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) { + Map map = of(); + map.put(k1, v1); + map.put(k2, v2); + map.put(k3, v3); + map.put(k4, v4); + map.put(k5, v5); + map.put(k6, v6); + map.put(k7, v7); + map.put(k8, v8); + return map; + } + } -- Gitee From e6b219aa1b698c84cf4ea4c41dd747ca0fb40ad3 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 29 Apr 2021 18:26:21 +0800 Subject: [PATCH 082/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/common/enums/KeywordEnum.java | 1 + .../com/sum/spirit/common/enums/TypeEnum.java | 2 +- .../main/java/com/sum/spirit/lib/Empty.java | 9 +++++ .../sum/spirit/core/api/ResolverContext.java | 2 ++ .../core/clazz/DefaultClassResolver.java | 5 +++ .../sum/spirit/core/clazz/entity/Import.java | 10 +++--- .../core/clazz/frame/ContextEntity.java | 10 +----- .../spirit/core/clazz/frame/ImportEntity.java | 33 ++++++++++++++--- .../spirit/core/clazz/frame/TypeEntity.java | 2 +- .../compile/linker/AdaptiveClassLinker.java | 4 +++ .../element/action/DefaultSemanticParser.java | 2 +- .../sum/spirit/output/java/JavaBuilder.java | 5 ++- .../output/java/action/EmptyAction.java | 35 +++++++++++++++++++ .../test/java/com/sum/test/block/Block.java | 6 +++- .../resources/com.sum.test/block/Block.sp | 5 ++- 15 files changed, 106 insertions(+), 25 deletions(-) create mode 100644 spirit-common/src/main/java/com/sum/spirit/lib/Empty.java create mode 100644 spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/EmptyAction.java diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/KeywordEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/KeywordEnum.java index 668b8775..23828238 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/KeywordEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/KeywordEnum.java @@ -36,6 +36,7 @@ public enum KeywordEnum { CATCH("catch", KeywordTypeEnum.TOKEN), // FINALLY("finally", KeywordTypeEnum.TOKEN), // INSTANCEOF("instanceof", KeywordTypeEnum.TOKEN), // + EMPTY("empty", KeywordTypeEnum.TOKEN), // PUBLIC("public", KeywordTypeEnum.MODIFIER), // PROTECTED("protected", KeywordTypeEnum.MODIFIER), // diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java index 2a34d4ac..61d2b39d 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java @@ -5,7 +5,7 @@ import java.util.regex.Pattern; public enum TypeEnum { ; public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); - public static final Pattern TYPE_END_PATTERN = Pattern.compile("^[\\s\\S]+\\.[A-Z]+\\w+$"); + public static final Pattern TYPE_END_PATTERN = Pattern.compile("^[\\s\\S]+\\.[A-Z]+\\w+(\\.[a-z]+\\w*)?$"); public static final Pattern TYPE_PATTERN = Pattern.compile("^[A-Z]+\\w*$"); public static final Pattern TYPE_ARRAY_PATTERN = Pattern.compile("^[A-Z]+\\w*\\[\\]$"); diff --git a/spirit-common/src/main/java/com/sum/spirit/lib/Empty.java b/spirit-common/src/main/java/com/sum/spirit/lib/Empty.java new file mode 100644 index 00000000..f8a4fdfa --- /dev/null +++ b/spirit-common/src/main/java/com/sum/spirit/lib/Empty.java @@ -0,0 +1,9 @@ +package com.sum.spirit.lib; + +public class Empty { + + public static boolean empty(String str) { + return str == null || str.length() == 0; + } + +} diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ResolverContext.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ResolverContext.java index a334cb5d..dbd9b027 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ResolverContext.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/api/ResolverContext.java @@ -4,6 +4,8 @@ import java.util.List; public interface ResolverContext { + ElementBuilder getElementBuilder(); + TypeFactory getTypeFactory(); List getImportSelectors(); diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java index 0a06956a..9422ca96 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/DefaultClassResolver.java @@ -125,6 +125,11 @@ public class DefaultClassResolver implements ClassResolver, ResolverContext { } } + @Override + public ElementBuilder getElementBuilder() { + return builder; + } + @Override public TypeFactory getTypeFactory() { return factory; diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/Import.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/Import.java index 2b3a48c3..d9f77685 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/Import.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/entity/Import.java @@ -1,7 +1,5 @@ package com.sum.spirit.core.clazz.entity; -import com.sum.spirit.common.utils.SpringUtils; -import com.sum.spirit.core.api.ElementBuilder; import com.sum.spirit.core.clazz.frame.ElementEntity; import com.sum.spirit.core.clazz.utils.TypeUtils; import com.sum.spirit.core.element.entity.Element; @@ -12,10 +10,6 @@ public class Import extends ElementEntity { super(element); } - public Import(String className) { - super(SpringUtils.getBean(ElementBuilder.class).build("import " + className)); - } - public String getClassName() { return element.getStr(1); } @@ -40,4 +34,8 @@ public class Import extends ElementEntity { return getClassName().equals(className); } + public boolean matchStaticSourceName(String staticSourceName) { + return element.getStr(2).equals(staticSourceName); + } + } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ContextEntity.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ContextEntity.java index 95a10b9e..078815b1 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ContextEntity.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ContextEntity.java @@ -1,17 +1,9 @@ package com.sum.spirit.core.clazz.frame; -import java.util.List; - import com.sum.spirit.core.api.ResolverContext; -import com.sum.spirit.core.clazz.entity.IAnnotation; -import com.sum.spirit.core.element.entity.Element; -public abstract class ContextEntity extends AnnotationEntity { +public abstract class ContextEntity { public ResolverContext context; - public ContextEntity(List annotations, Element element) { - super(annotations, element); - } - } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java index 971f0eff..8e3e7e5c 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/ImportEntity.java @@ -6,6 +6,7 @@ import java.util.stream.Collectors; import com.sum.spirit.common.enums.PrimitiveEnum; import com.sum.spirit.common.utils.ListUtils; +import com.sum.spirit.core.api.ElementBuilder; import com.sum.spirit.core.clazz.entity.IAnnotation; import com.sum.spirit.core.clazz.entity.Import; import com.sum.spirit.core.clazz.utils.TypeUtils; @@ -13,21 +14,27 @@ import com.sum.spirit.core.element.entity.Element; import cn.hutool.core.lang.Assert; -public abstract class ImportEntity extends ContextEntity { +public abstract class ImportEntity extends AnnotationEntity { public List imports; + public List staticImports; public ImportEntity(List imports, List annotations, Element element) { super(annotations, element); this.imports = imports != null ? new ArrayList<>(imports) : new ArrayList<>(); + this.staticImports = new ArrayList<>(); } public List getImports() { - return imports.stream().filter(imp -> !imp.hasAlias()).collect(Collectors.toList()); + return imports.stream().filter(import0 -> !import0.hasAlias()).collect(Collectors.toList()); } public List getAliasImports() { - return imports.stream().filter(imp -> imp.hasAlias()).collect(Collectors.toList()); + return imports.stream().filter(import0 -> import0.hasAlias()).collect(Collectors.toList()); + } + + public List getStaticImports() { + return staticImports; } public Import findImport(String className) { @@ -38,6 +45,10 @@ public abstract class ImportEntity extends ContextEntity { return ListUtils.findOne(imports, import0 -> import0.matchSimpleName(simpleName)); } + public Import findStaticImport(String staticSourceName) { + return ListUtils.findOne(staticImports, import0 -> import0.matchStaticSourceName(staticSourceName)); + } + public String findClassName(String simpleName) { // 校验 Assert.notContain(simpleName, ".", "Simple name cannot contains \".\""); @@ -93,7 +104,21 @@ public abstract class ImportEntity extends ContextEntity { return true; } - imports.add(new Import(targetName)); + // 构建一个行元素 + ElementBuilder builder = context.getElementBuilder(); + imports.add(new Import(builder.build("import " + targetName))); + return true; + } + + public boolean addStaticImport(String staticSourceName) { + // 如果已经有了,直接返回true + Import import0 = findStaticImport(staticSourceName); + if (import0 != null) { + return true; + } + // 构建一个行元素 + ElementBuilder builder = context.getElementBuilder(); + staticImports.add(new Import(builder.build("import static " + staticSourceName))); return true; } diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TypeEntity.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TypeEntity.java index 23a0b3e4..e922d9ce 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TypeEntity.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/frame/TypeEntity.java @@ -8,7 +8,7 @@ import lombok.Setter; @Getter @Setter -public abstract class TypeEntity { +public abstract class TypeEntity extends ContextEntity { @NonNull private IType type; } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java index e4b801c9..7c35b952 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java @@ -132,6 +132,10 @@ public class AdaptiveClassLinker implements ClassLinker { if (type.isArray()) { throw new RuntimeException("Array has no method!"); } + // 如果已经推导到Object,并且方法名是empty的话,则直接返回布尔类型 + if (StaticTypes.OBJECT.equals(type) && KeywordEnum.EMPTY.value.equals(methodName)) { + return StaticTypes.BOOLEAN; + } // 向上遍历推导 IType returnType = getLinker(type).visitMethod(type, methodName, parameterTypes); if (returnType == null) { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java index 98f09289..1d4ccbbc 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java @@ -87,7 +87,7 @@ public class DefaultSemanticParser extends AbstractSemanticParser { List words = insideType ? lexer.getSubWords(word, '<', '>') : lexer.getSubWords(word, '(', ')', '[', ']', '{', '}'); List tokens = null; String first = words.get(0); - + // 如果第一个单词是一个前缀的话,则添加前缀 if (PREFIX_PATTERN.matcher(first).matches()) { List subWords = words.subList(1, words.size()); diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java index 488e9a8c..e79c5f71 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/JavaBuilder.java @@ -51,7 +51,10 @@ public class JavaBuilder implements CodeBuilder, InitializingBean { // import List imports = clazz.getImports(); imports.forEach((imp) -> builder.append(imp.element + ";\n")); - if (imports.size() > 0) { + // static import + List staticImports = clazz.getStaticImports(); + staticImports.forEach((imp) -> builder.append(imp.element + ";\n")); + if (imports.size() > 0 || staticImports.size() > 0) { builder.append("\n"); } // annotation diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/EmptyAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/EmptyAction.java new file mode 100644 index 00000000..74939e6a --- /dev/null +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/EmptyAction.java @@ -0,0 +1,35 @@ +package com.sum.spirit.output.java.action; + +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import com.sum.spirit.common.annotation.Native; +import com.sum.spirit.common.constants.Attribute; +import com.sum.spirit.core.clazz.entity.IClass; +import com.sum.spirit.core.compile.action.AbstractElementAction; +import com.sum.spirit.core.compile.entity.ElementEvent; +import com.sum.spirit.core.element.entity.Statement; +import com.sum.spirit.core.element.utils.StmtVisiter; +import com.sum.spirit.lib.Empty; + +@Native +@Component +@Order(-120) +public class EmptyAction extends AbstractElementAction { + + @Override + public void handle(ElementEvent event) { + IClass clazz = event.clazz; + Statement statement = event.element; + StmtVisiter.visit(statement, stmt -> { + stmt.forEach(token -> { + if (token.isLocalMethod()) {// empty(str) + if ("empty".equals(token.attr(Attribute.MEMBER_NAME))) { + clazz.addStaticImport(Empty.class.getName() + ".empty"); + } + } + }); + }); + } + +} diff --git a/spirit-test/src/test/java/com/sum/test/block/Block.java b/spirit-test/src/test/java/com/sum/test/block/Block.java index d0a5b56d..d66e6827 100644 --- a/spirit-test/src/test/java/com/sum/test/block/Block.java +++ b/spirit-test/src/test/java/com/sum/test/block/Block.java @@ -8,6 +8,7 @@ import java.util.Map; import java.util.Map.Entry; import com.sum.spirit.lib.Lists; import java.util.List; +import static com.sum.spirit.lib.Empty.empty; public class Block { @@ -21,7 +22,10 @@ public class Block { if (!StringUtils.equals(s, "hello")) { logger.info(s); } - if (StringUtils.isNotEmpty(s)) { + if (empty(s)) { + logger.info(s); + } + if (!empty(s)) { logger.info(s); } if (!StringUtils.isNotEmpty(s)) { diff --git a/spirit-test/src/test/resources/com.sum.test/block/Block.sp b/spirit-test/src/test/resources/com.sum.test/block/Block.sp index b63913a0..29e02ced 100644 --- a/spirit-test/src/test/resources/com.sum.test/block/Block.sp +++ b/spirit-test/src/test/resources/com.sum.test/block/Block.sp @@ -11,7 +11,10 @@ class Block { if s!="hello"{ print s } - if s { + if empty(s) { + print s + } + if !empty(s) { print s } if !s { -- Gitee From 0bb7e477babdb05c6ab389cc7b207323e39dcccc Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 29 Apr 2021 18:37:39 +0800 Subject: [PATCH 083/121] =?UTF-8?q?=E6=B7=BB=E5=8A=A0empty=E5=88=A4?= =?UTF-8?q?=E7=A9=BA=E5=85=B3=E9=94=AE=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sublime-plugs/Spirit.sublime-syntax | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sublime-plugs/Spirit.sublime-syntax b/sublime-plugs/Spirit.sublime-syntax index 0ecafc08..9e986f25 100644 --- a/sublime-plugs/Spirit.sublime-syntax +++ b/sublime-plugs/Spirit.sublime-syntax @@ -30,7 +30,7 @@ contexts: scope: keyword # Block Keyword - - match: '\b(super|this|return|continue|break|throw|instanceof|print|debug|error)\b' + - match: '\b(super|this|return|continue|break|throw|instanceof|print|debug|error|empty)\b' scope: keyword # Basic Type -- Gitee From f6eab76eae6f3ccfd7ced5cd183e2615ce33bddd Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 30 Apr 2021 09:53:36 +0800 Subject: [PATCH 084/121] =?UTF-8?q?=E5=8E=BB=E6=8E=89string=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E9=9A=90=E5=BC=8F=E8=BD=AC=E6=8D=A2=EF=BC=8C=E6=94=B9?= =?UTF-8?q?=E7=94=A8empty=E5=85=B3=E9=94=AE=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../output/java/action/CommonAction.java | 2 +- .../output/java/action/EmptyAction.java | 5 +- .../java/action/StringEqualsAction.java | 2 +- .../output/java/action/StringLogicAction.java | 74 ------------------- .../test/java/com/sum/test/block/Block.java | 5 -- .../java/com/sum/test/subexpress/Express.java | 3 +- .../resources/com.sum.test/block/Block.sp | 5 -- .../com.sum.test/subexpress/Express.sp | 2 +- 8 files changed, 8 insertions(+), 90 deletions(-) delete mode 100644 spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java index 9ae3e715..e640eb7e 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/CommonAction.java @@ -16,7 +16,7 @@ import com.sum.spirit.lib.Maps; @Native @Component -@Order(-100) +@Order(-80) public class CommonAction extends AbstractElementAction { @Override diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/EmptyAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/EmptyAction.java index 74939e6a..b7429b89 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/EmptyAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/EmptyAction.java @@ -5,6 +5,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.annotation.Native; import com.sum.spirit.common.constants.Attribute; +import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.compile.action.AbstractElementAction; import com.sum.spirit.core.compile.entity.ElementEvent; @@ -14,7 +15,7 @@ import com.sum.spirit.lib.Empty; @Native @Component -@Order(-120) +@Order(-100) public class EmptyAction extends AbstractElementAction { @Override @@ -24,7 +25,7 @@ public class EmptyAction extends AbstractElementAction { StmtVisiter.visit(statement, stmt -> { stmt.forEach(token -> { if (token.isLocalMethod()) {// empty(str) - if ("empty".equals(token.attr(Attribute.MEMBER_NAME))) { + if (KeywordEnum.EMPTY.value.equals(token.attr(Attribute.MEMBER_NAME))) { clazz.addStaticImport(Empty.class.getName() + ".empty"); } } diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java index 0248e16b..e0b1f0c2 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringEqualsAction.java @@ -19,7 +19,7 @@ import com.sum.spirit.output.java.utils.TypeUtils; @Native @Component -@Order(-80) +@Order(-60) public class StringEqualsAction extends AbstractTreeElementAction { public static final String FORMAT = "StringUtils.equals(%s, %s)"; diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java deleted file mode 100644 index 022cdabb..00000000 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/action/StringLogicAction.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.sum.spirit.output.java.action; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; - -import com.sum.spirit.common.annotation.Native; -import com.sum.spirit.common.constants.Attribute; -import com.sum.spirit.common.enums.TokenTypeEnum; -import com.sum.spirit.core.clazz.entity.IClass; -import com.sum.spirit.core.clazz.entity.IType; -import com.sum.spirit.core.clazz.utils.StaticTypes; -import com.sum.spirit.core.element.entity.Statement; -import com.sum.spirit.core.element.entity.Token; -import com.sum.spirit.output.java.utils.TypeUtils; - -@Native -@Component -@Order(-60) -public class StringLogicAction extends AbstractTreeElementAction { - - public static final String FORMAT = "StringUtils.isNotEmpty(%s)"; - - @Override - public boolean isTrigger(Token currentToken) { - return currentToken.isLogical() && (currentToken.isNegate() || currentToken.isLogicAnd() || currentToken.isLogicOr()); - } - - @Override - public void visit(IClass clazz, Statement statement, int index, Token currentToken) { - Map context = new HashMap<>(); - if (currentToken.isNegate()) { - visitNext(clazz, statement, index, currentToken, context); - - } else if (currentToken.isLogicAnd() || currentToken.isLogicOr()) { - visitPrev(clazz, statement, index, currentToken, context); - visitNext(clazz, statement, index, currentToken, context); - } - } - - @Override - public void doVisitPrev(IClass clazz, Statement statement, int index, Token currentToken, Map context) { - int start = (Integer) context.get(START); - Statement prevStatement = (Statement) context.get(PREV_STATEMENT); - IType prevType = (IType) context.get(PREV_TYPE); - if (TypeUtils.isString(prevType)) { - String text = String.format(FORMAT, prevStatement); - Token expressToken = new Token(TokenTypeEnum.CUSTOM_EXPRESS, text); - expressToken.setAttr(Attribute.TYPE, StaticTypes.BOOLEAN); - expressToken.setAttr(Attribute.TREE_ID, currentToken.attr(Attribute.TREE_ID) + "-0"); - statement.replaceTokens(start, index, expressToken); - clazz.addImport(StringUtils.class.getName()); - } - } - - @Override - public void doVisitNext(IClass clazz, Statement statement, int index, Token currentToken, Map context) { - int end = (Integer) context.get(END); - Statement nextStatement = (Statement) context.get(NEXT_STATEMENT); - IType nextType = (IType) context.get(NEXT_TYPE); - if (TypeUtils.isString(nextType)) { - String text = String.format(FORMAT, nextStatement); - Token expressToken = new Token(TokenTypeEnum.CUSTOM_EXPRESS, text); - expressToken.setAttr(Attribute.TYPE, StaticTypes.BOOLEAN); - expressToken.setAttr(Attribute.TREE_ID, currentToken.attr(Attribute.TREE_ID) + "-1"); - statement.replaceTokens(index + 1, end, expressToken); - clazz.addImport(StringUtils.class.getName()); - } - } - -} diff --git a/spirit-test/src/test/java/com/sum/test/block/Block.java b/spirit-test/src/test/java/com/sum/test/block/Block.java index d66e6827..ad97a0ea 100644 --- a/spirit-test/src/test/java/com/sum/test/block/Block.java +++ b/spirit-test/src/test/java/com/sum/test/block/Block.java @@ -28,11 +28,6 @@ public class Block { if (!empty(s)) { logger.info(s); } - if (!StringUtils.isNotEmpty(s)) { - logger.info(s); - } else { - logger.info(s); - } if (StringUtils.isNotEmpty(s)) { logger.info(s); } diff --git a/spirit-test/src/test/java/com/sum/test/subexpress/Express.java b/spirit-test/src/test/java/com/sum/test/subexpress/Express.java index 297ac594..c7052a8b 100644 --- a/spirit-test/src/test/java/com/sum/test/subexpress/Express.java +++ b/spirit-test/src/test/java/com/sum/test/subexpress/Express.java @@ -5,6 +5,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sum.spirit.lib.Lists; import java.util.List; +import static com.sum.spirit.lib.Empty.empty; public class Express { @@ -45,7 +46,7 @@ public class Express { logger.info("{}", express1); boolean b11 = (x + 1 > 0 && y < 100) && StringUtils.equals(list.get(0), "test") && s instanceof Object; logger.info("{}", b11); - boolean b111 = (!StringUtils.equals(s, "test")) && StringUtils.equals(s, "test") && StringUtils.isNotEmpty(list.get(0)) && StringUtils.isNotEmpty(s) && (!StringUtils.isNotEmpty(s)); + boolean b111 = (!StringUtils.equals(s, "test")) && StringUtils.equals(s, "test") && !empty(list.get(0)); logger.info("{}", b111); String b222 = list.get(1).toString(); logger.info("{}", b222); diff --git a/spirit-test/src/test/resources/com.sum.test/block/Block.sp b/spirit-test/src/test/resources/com.sum.test/block/Block.sp index 29e02ced..ec8efbfe 100644 --- a/spirit-test/src/test/resources/com.sum.test/block/Block.sp +++ b/spirit-test/src/test/resources/com.sum.test/block/Block.sp @@ -17,11 +17,6 @@ class Block { if !empty(s) { print s } - if !s { - print s - }else{ - print s - } if s : print s diff --git a/spirit-test/src/test/resources/com.sum.test/subexpress/Express.sp b/spirit-test/src/test/resources/com.sum.test/subexpress/Express.sp index 4459bf32..0bd557f8 100644 --- a/spirit-test/src/test/resources/com.sum.test/subexpress/Express.sp +++ b/spirit-test/src/test/resources/com.sum.test/subexpress/Express.sp @@ -39,7 +39,7 @@ class Express { b11=(x +1 >0 && y <100 ) && list.get(0)=="test" && s instanceof Object print "{}",b11 - b111=( s!="test" ) && s=="test" && list.get(0) && s && (!s) + b111=( s!="test" ) && s=="test" && !empty(list.get(0)) print "{}",b111 b222=list.get(1).toString() -- Gitee From a0bccc11b96827131ce4a89c1cf1237f3bce9a3f Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 30 Apr 2021 10:17:02 +0800 Subject: [PATCH 085/121] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../compile/action/AbstractElementAction.java | 17 ------------- .../action/AbstractScopeElementAction.java | 25 +++++++++++++++++++ .../action/ElementExpressDeclarer.java | 2 +- .../compile/action/ElementTypeDeclarer.java | 2 +- .../core/compile/entity/ElementEvent.java | 4 +++ 5 files changed, 31 insertions(+), 19 deletions(-) create mode 100644 spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractScopeElementAction.java diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractElementAction.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractElementAction.java index f265966f..c33d575c 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractElementAction.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractElementAction.java @@ -10,21 +10,4 @@ public abstract class AbstractElementAction implements ElementAction { return event.element != null; } - @Override - public void handle(ElementEvent event) { - if (!event.isMethodScope()) { - visitFieldScope(event); - } else { - visitMethodScope(event); - } - } - - public void visitFieldScope(ElementEvent event) { - // ignore - } - - public void visitMethodScope(ElementEvent event) { - // ignore - } - } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractScopeElementAction.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractScopeElementAction.java new file mode 100644 index 00000000..e8ea3688 --- /dev/null +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/AbstractScopeElementAction.java @@ -0,0 +1,25 @@ +package com.sum.spirit.core.compile.action; + +import com.sum.spirit.core.compile.entity.ElementEvent; + +public abstract class AbstractScopeElementAction extends AbstractElementAction { + + @Override + public void handle(ElementEvent event) { + if (event.isFieldScope()) { + visitFieldScope(event); + + } else if (event.isMethodScope()) { + visitMethodScope(event); + } + } + + public void visitFieldScope(ElementEvent event) { + // ignore + } + + public void visitMethodScope(ElementEvent event) { + // ignore + } + +} diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java index 869caab8..befaa506 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java @@ -24,7 +24,7 @@ import com.sum.spirit.core.element.entity.Token; @App @Component @Order(-80) -public class ElementExpressDeclarer extends AbstractElementAction { +public class ElementExpressDeclarer extends AbstractScopeElementAction { @Autowired public ElementBuilder builder; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java index 9ba90b2c..55977293 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementTypeDeclarer.java @@ -15,7 +15,7 @@ import com.sum.spirit.core.element.entity.Token; @App @Component @Order(-100) -public class ElementTypeDeclarer extends AbstractElementAction { +public class ElementTypeDeclarer extends AbstractScopeElementAction { @Autowired public TypeFactory factory; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity/ElementEvent.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity/ElementEvent.java index 4536c735..079c2f6d 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity/ElementEvent.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/entity/ElementEvent.java @@ -20,6 +20,10 @@ public class ElementEvent { this.context = context; } + public boolean isFieldScope() { + return context == null; + } + public boolean isMethodScope() { return context != null; } -- Gitee From 26db5c60fd2c0ecf83d16fc19e6e6d2d0d566520 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 30 Apr 2021 10:18:04 +0800 Subject: [PATCH 086/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/compile/action/ElementExpressDeclarer.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java index befaa506..218dcffb 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java @@ -26,10 +26,6 @@ import com.sum.spirit.core.element.entity.Token; @Order(-80) public class ElementExpressDeclarer extends AbstractScopeElementAction { - @Autowired - public ElementBuilder builder; - @Autowired - public DefaultElementVisiter elementVisiter; @Autowired public VariableTracker tracker; @Autowired @@ -38,6 +34,10 @@ public class ElementExpressDeclarer extends AbstractScopeElementAction { public FragmentDeducer deducer; @Autowired public TypeDerivator derivator; + @Autowired + public ElementBuilder builder; + @Autowired + public DefaultElementVisiter elementVisiter; @Override public void handle(ElementEvent event) { -- Gitee From bd0736a11ba2069e1a69e9f2b000969fe6d0708f Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Fri, 30 Apr 2021 19:04:59 +0800 Subject: [PATCH 087/121] =?UTF-8?q?=E9=87=8D=E6=9E=84=E8=AF=8D=E6=B3=95?= =?UTF-8?q?=E5=88=86=E6=9E=90=E5=99=A8=EF=BC=8C=E4=BD=BF=E7=94=A8=E6=A0=87?= =?UTF-8?q?=E8=AE=B0=E8=A1=A5=E5=85=85=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../element/action/DefaultSemanticParser.java | 2 +- .../com/sum/spirit/core/api/CharsHandler.java | 2 +- .../com/sum/spirit/core/api/LexerAction.java | 12 +++ .../core/lexer/AbstractCharsHandler.java | 10 +- ...orAction.java => AbstractCursorLexer.java} | 36 +------ .../sum/spirit/core/lexer/AbstractLexer.java | 79 ++++++++++++++ .../com/sum/spirit/core/lexer/CoreLexer.java | 100 ++---------------- .../core/lexer/action/BorderAction.java | 22 ++-- .../core/lexer/action/RegionAction.java | 68 ++++++------ .../spirit/core/lexer/action/SpaceAction.java | 28 +++++ .../core/lexer/action/SymbolAction.java | 20 ++-- .../core/lexer/entity/LexerContext.java | 18 ++-- .../spirit/core/lexer/entity/LexerResult.java | 18 ++++ .../sum/spirit/core/lexer/entity/Region.java | 4 + .../RegionUtils.java} | 56 +++++++--- .../sum/spirit/core/lexer/test/LexerTest.java | 46 ++++++++ 16 files changed, 304 insertions(+), 217 deletions(-) create mode 100644 spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/LexerAction.java rename spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/{action/CursorAction.java => AbstractCursorLexer.java} (48%) create mode 100644 spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java create mode 100644 spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SpaceAction.java create mode 100644 spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java rename spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/{action/AbstractLexerAction.java => utils/RegionUtils.java} (35%) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java index 1d4ccbbc..08e02204 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java @@ -63,7 +63,7 @@ public class DefaultSemanticParser extends AbstractSemanticParser { token.tokenType = getAccessTokenType(word); } - Assert.notNull(token.tokenType, "Token type cannot be null!"); + Assert.notNull(token.tokenType, "Token type cannot be null!word:[" + word + "]"); } public void setTokenValue(String word, Token token) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/CharsHandler.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/CharsHandler.java index 95fce938..b31e4be6 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/CharsHandler.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/CharsHandler.java @@ -4,6 +4,6 @@ import com.sum.spirit.core.lexer.entity.CharsContext; public interface CharsHandler { - void handle(CharsContext context, StringBuilder builder, CharAction action); + void handle(CharsContext context, StringBuilder builder); } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/LexerAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/LexerAction.java new file mode 100644 index 00000000..59c84cb6 --- /dev/null +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/LexerAction.java @@ -0,0 +1,12 @@ +package com.sum.spirit.core.api; + +import com.sum.spirit.core.lexer.entity.CharEvent; +import com.sum.spirit.core.lexer.entity.LexerResult; + +public interface LexerAction { + + boolean isTrigger(CharEvent event); + + LexerResult handle(CharEvent event); + +} diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCharsHandler.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCharsHandler.java index a9993aa0..59bc6c75 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCharsHandler.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCharsHandler.java @@ -8,18 +8,14 @@ import com.sum.spirit.core.lexer.entity.CharsContext; public abstract class AbstractCharsHandler implements CharsHandler, CharAction { @Override - public void handle(CharsContext context, StringBuilder builder, CharAction action) { + public void handle(CharsContext context, StringBuilder builder) { for (; context.index < builder.length(); context.index++) { char ch = builder.charAt(context.index); CharEvent event = new CharEvent(context, ch); - if (action.isTrigger(event)) { - action.handle(event); + if (this.isTrigger(event)) { + this.handle(event); } } } - public void handle(CharsContext context, StringBuilder builder) { - handle(context, builder, this); - } - } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/CursorAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCursorLexer.java similarity index 48% rename from spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/CursorAction.java rename to spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCursorLexer.java index c3af44dd..b7bb00f4 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/CursorAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCursorLexer.java @@ -1,27 +1,11 @@ -package com.sum.spirit.core.lexer.action; +package com.sum.spirit.core.lexer; import com.sum.spirit.common.utils.LineUtils; -import com.sum.spirit.core.api.CharAction; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; -public class CursorAction implements CharAction { - - public CharAction action; - - public CursorAction(CharAction action) { - this.action = action; - } +public abstract class AbstractCursorLexer extends AbstractLexer { - @Override - public boolean isTrigger(CharEvent event) { - return true; - } - - /** - * -接续字符和刷新字符,是游标敏感的,用以标记区域的起始位置 - * -先进行弹栈,再刷新startIndex为-1,例如“[”这种情况 - */ @Override public void handle(CharEvent event) { LexerContext context = (LexerContext) event.context; @@ -29,30 +13,16 @@ public class CursorAction implements CharAction { if ((context.startIndex < 0 && isContinuous(ch)) || isRefreshed(ch)) { context.startIndex = context.index; } - if (action.isTrigger(event)) { - action.handle(event); - } + super.handle(event); if (!isContinuous(ch)) { context.startIndex = -1; } } - /** - * -是否接续字符 - * - * @param ch - * @return - */ public boolean isContinuous(char ch) { return LineUtils.isLetter(ch) || ch == '@' || ch == '.'; } - /** - * -是否刷新字符 - * - * @param ch - * @return - */ public boolean isRefreshed(char ch) { return ch == '.'; } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java new file mode 100644 index 00000000..19dff636 --- /dev/null +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java @@ -0,0 +1,79 @@ +package com.sum.spirit.core.lexer; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.sum.spirit.common.enums.LiteralEnum; +import com.sum.spirit.common.enums.TypeEnum; +import com.sum.spirit.core.api.Lexer; +import com.sum.spirit.core.api.LexerAction; +import com.sum.spirit.core.lexer.entity.CharEvent; +import com.sum.spirit.core.lexer.entity.CharsContext; +import com.sum.spirit.core.lexer.entity.LexerContext; +import com.sum.spirit.core.lexer.entity.LexerResult; +import com.sum.spirit.core.lexer.entity.Region; +import com.sum.spirit.core.lexer.utils.RegionUtils; +import com.sum.spirit.core.lexer.entity.LexerResult.State; + +public abstract class AbstractLexer extends AbstractCharsHandler implements Lexer { + + @Autowired + public List actions; + + @Override + public void handle(CharsContext context, StringBuilder builder) { + super.handle(context, builder); + completeRegions(context, builder);// 使用标记收集算法后,补全未标记的部分 + } + + public void completeRegions(CharsContext context, StringBuilder builder) { + LexerContext lexerContext = (LexerContext) context; + if (lexerContext.words == null) { + List regions = lexerContext.regions; + Set completedRegions = new HashSet(); + regions = RegionUtils.completeRegions(builder, regions, region -> completedRegions.add(region)); + lexerContext.words = RegionUtils.subRegions(builder, regions, (words, region, text) -> addToWords(words, completedRegions, region, text)); + } + } + + public void addToWords(List words, Set completedRegions, Region region, String text) { + if (completedRegions.contains(region)) { + if (text.indexOf(".") > 0 && !LiteralEnum.isDouble(text) && !TypeEnum.isTypeEnd(text)) { + List subWords = Arrays.asList(text.replaceAll("\\.", " .").split(" ")); + words.addAll(subWords); + } else { + words.add(text); + } + } else { + words.add(text); + } + } + + @Override + public boolean isTrigger(CharEvent event) { + return true; + } + + @Override + public void handle(CharEvent event) { + for (LexerAction action : actions) { + if (action.isTrigger(event)) { + LexerResult result = action.handle(event); + if (result.region != null) { + LexerContext context = (LexerContext) event.context; + context.regions.add(result.region); + } + if (result.state == State.TRY) { + continue; + } else if (result.state == State.SKIP) { + break; + } + } + } + } + +} diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java index 4afde66f..75160145 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java @@ -1,72 +1,34 @@ package com.sum.spirit.core.lexer; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; -import java.util.Map; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; -import com.sum.spirit.common.enums.LiteralEnum; -import com.sum.spirit.common.enums.TypeEnum; -import com.sum.spirit.common.utils.LineUtils; -import com.sum.spirit.common.utils.SpringUtils; -import com.sum.spirit.core.api.CharAction; -import com.sum.spirit.core.api.Lexer; -import com.sum.spirit.core.lexer.action.AbstractLexerAction; import com.sum.spirit.core.lexer.action.BorderAction; -import com.sum.spirit.core.lexer.action.CursorAction; -import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; import cn.hutool.core.lang.Assert; @Component -@DependsOn("springUtils") -public class CoreLexer extends AbstractCharsHandler implements Lexer, InitializingBean { +public class CoreLexer extends AbstractCursorLexer { - public List actions; - @Autowired - public BorderAction borderAction; - - @Override - public void afterPropertiesSet() throws Exception { - actions = SpringUtils.getBeansByExcludedTypes(AbstractLexerAction.class, BorderAction.class); - } - - /** - * -1.整体替换语句中的某些区域 - * -2.去掉多余的空格 - * -3.利用空格,进行拆分 - * -4.继续拆分带有“.”的单词 - * -5.还原被替换的单词 - */ @Override public List getWords(String text) { - Assert.notBlank(text, "text cannot be blank!"); + Assert.notBlank(text, "Text cannot be blank!"); StringBuilder builder = new StringBuilder(text.trim()); LexerContext context = new LexerContext(builder); - handle(context, builder, new CursorAction(this)); - text = LineUtils.mergeSpaces(context.builder.toString()); - List words = new ArrayList<>(Arrays.asList(text.split(" "))); - splitWords(words); - restoreWords(words, context.replacedStrs); - return words; + handle(context, builder); + return context.words; } - /** - * -根据弹栈规则,拆分分隔符和单词 - */ @Override public List getSubWords(String text, Character... splitChars) { - Assert.notBlank(text, "text cannot be blank!"); + Assert.notBlank(text, "Text cannot be blank!"); StringBuilder builder = new StringBuilder(text.trim()); - LexerContext context = new LexerContext(builder, splitChars); - handle(context, builder, new CursorAction(borderAction)); - Assert.notNull(context.words, "words of context cannot be null!"); + LexerContext context = new LexerContext(builder, BorderAction.PROFILE, splitChars); + handle(context, builder); + Assert.notNull(context.words, "Words of context cannot be null!"); List words = new ArrayList<>(); for (String word : context.words) { if (word.length() == 1) { @@ -78,50 +40,4 @@ public class CoreLexer extends AbstractCharsHandler implements Lexer, Initializi return words; } - /** - * -继续拆分带有“.”的单词 - * - * @param words - */ - public void splitWords(List words) { - for (int index = 0; index < words.size(); index++) { - String word = words.get(index); - if (word.indexOf(".") > 0 && !LiteralEnum.isDouble(word) && !TypeEnum.isTypeEnd(word)) { - List subWords = Arrays.asList(word.replaceAll("\\.", " .").split(" ")); - words.remove(index); - words.addAll(index, subWords); - } - } - } - - /** - * -替换之前被替换的单词 - * - * @param words - * @param replacedStrs - */ - public void restoreWords(List words, Map replacedStrs) { - for (int index = 0; index < words.size(); index++) { - String str = replacedStrs.get(words.get(index)); - if (str != null) { - words.set(index, str); - } - } - } - - @Override - public boolean isTrigger(CharEvent event) { - return true; - } - - @Override - public void handle(CharEvent event) { - for (CharAction action : actions) { - if (action.isTrigger(event)) { - action.handle(event); - return; - } - } - } - } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java index 07ee63bf..c636eafe 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java @@ -3,22 +3,30 @@ package com.sum.spirit.core.lexer.action; import java.util.ArrayList; import java.util.List; +import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.utils.Splitter; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; +import com.sum.spirit.core.lexer.entity.LexerResult; import com.sum.spirit.core.lexer.entity.Region; +import com.sum.spirit.core.lexer.entity.LexerResult.State; @Component +@Order(-100) public class BorderAction extends RegionAction { - /** - * -该类对弹栈行为进行了一定改造,主要对分隔符进行拆分,并将索引直接置为结束 - */ + public static final String PROFILE = "BORDER_ACTION"; + @Override - public void pushStack(CharEvent event, List regions, String markName) { + public boolean isTrigger(CharEvent event) { + LexerContext context = (LexerContext) event.context; + return PROFILE.equals(context.profile) && super.isTrigger(event); + } + @Override + public LexerResult pushStack(CharEvent event, List regions) { LexerContext context = (LexerContext) event.context; StringBuilder builder = context.builder; List splitChars = context.splitChars; @@ -35,11 +43,7 @@ public class BorderAction extends RegionAction { context.words = Splitter.splitByIndexsTrimRemain(builder.toString(), indexs); context.index = builder.length(); - } - - @Override - public void resetIndex(CharEvent event) { - // ignore + return new LexerResult(State.SKIP, null); } } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java index 61531bcf..7087bfa6 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java @@ -7,18 +7,18 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.TypeEnum; import com.sum.spirit.common.utils.ListUtils; +import com.sum.spirit.core.api.LexerAction; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; +import com.sum.spirit.core.lexer.entity.LexerResult; +import com.sum.spirit.core.lexer.entity.LexerResult.State; import com.sum.spirit.core.lexer.entity.Region; +import com.sum.spirit.core.lexer.utils.RegionUtils; @Component -@Order(-100) -public class RegionAction extends AbstractLexerAction { +@Order(-80) +public class RegionAction implements LexerAction { - /** - * -到达结尾,则直接返回false - * -泛型前缀一般都以大写字母开始 - */ @Override public boolean isTrigger(CharEvent event) { LexerContext context = (LexerContext) event.context; @@ -43,73 +43,65 @@ public class RegionAction extends AbstractLexerAction { return false; } - /** - * str[0] => str [0], String[0] => String[0], String[]{"str", "str"} => String[]{"str", "str"} - */ @Override - public void handle(CharEvent event) { - + public LexerResult handle(CharEvent event) { LexerContext context = (LexerContext) event.context; StringBuilder builder = context.builder; char ch = event.ch; if (ch == '"') { - Region region = findRegion(builder, context.index, '"', '"'); - pushStack(event, ListUtils.toListNonNull(region), "@str"); + Region region = RegionUtils.findRegion(builder, context.index, '"', '"'); + return pushStack(event, ListUtils.toListNonNull(region)); } else if (ch == '\'') { - Region region = findRegion(builder, context.index, '\'', '\''); - pushStack(event, ListUtils.toListNonNull(region), "@char"); + Region region = RegionUtils.findRegion(builder, context.index, '\'', '\''); + return pushStack(event, ListUtils.toListNonNull(region)); } else if (ch == '{') { - Region region = findRegion(builder, context.index, '{', '}'); - pushStack(event, ListUtils.toListNonNull(region), "@map"); + Region region = RegionUtils.findRegion(builder, context.index, '{', '}'); + return pushStack(event, ListUtils.toListNonNull(region)); } else if (ch == '(') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; - Region region1 = findRegion(builder, context.index, '(', ')'); - pushStack(event, ListUtils.toListNonNull(region0, region1), "@invoke_like"); - resetIndex(event); + Region region1 = RegionUtils.findRegion(builder, context.index, '(', ')'); + return pushStack(event, ListUtils.toListNonNull(region0, region1)); } else if (ch == '[') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; - if (region0 != null && !TypeEnum.isTypePrefix(subRegion(builder, region0))) { + if (region0 != null && !TypeEnum.isTypePrefix(RegionUtils.subRegion(builder, region0))) { region0 = null; } - Region region1 = findRegion(builder, context.index, '[', ']'); + Region region1 = RegionUtils.findRegion(builder, context.index, '[', ']'); Region region2 = null; if (region0 != null) { if (isCharAt(builder, region1.endIndex, '{')) { - region2 = findRegion(builder, region1.endIndex, '{', '}'); + region2 = RegionUtils.findRegion(builder, region1.endIndex, '{', '}'); } else if (isCharAt(builder, region1.endIndex, ' ') && isCharAt(builder, region1.endIndex + 1, '{')) { - region2 = findRegion(builder, region1.endIndex + 1, '{', '}'); + region2 = RegionUtils.findRegion(builder, region1.endIndex + 1, '{', '}'); } } - pushStack(event, ListUtils.toListNonNull(region0, region1, region2), "@array_like"); - resetIndex(event); + return pushStack(event, ListUtils.toListNonNull(region0, region1, region2)); } else if (ch == '<') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; - Region region1 = findRegion(builder, context.index, '<', '>'); - Region region2 = isCharAt(builder, region1.endIndex, '(') ? findRegion(builder, region1.endIndex, '(', ')') : null; - pushStack(event, ListUtils.toListNonNull(region0, region1, region2), "@generic"); - resetIndex(event); + Region region1 = RegionUtils.findRegion(builder, context.index, '<', '>'); + Region region2 = isCharAt(builder, region1.endIndex, '(') ? RegionUtils.findRegion(builder, region1.endIndex, '(', ')') : null; + return pushStack(event, ListUtils.toListNonNull(region0, region1, region2)); } - } - public boolean isCharAt(StringBuilder builder, int index, char ch) { - return index < builder.length() && builder.charAt(index) == ch; + throw new RuntimeException("Can't handle the scene!"); } - public void pushStack(CharEvent event, List regions, String markName) { + public LexerResult pushStack(CharEvent event, List regions) { LexerContext context = (LexerContext) event.context; - replaceRegion(context.builder, mergeRegions(regions), markName + context.nameCount++, context.replacedStrs); + Region mergedRegion = RegionUtils.mergeRegions(regions); + context.index = mergedRegion.endIndex - 1; + return new LexerResult(State.SKIP, mergedRegion); } - public void resetIndex(CharEvent event) { - LexerContext context = (LexerContext) event.context; - context.index = context.startIndex >= 0 ? context.startIndex : context.index; + public boolean isCharAt(StringBuilder builder, int index, char ch) { + return index < builder.length() && builder.charAt(index) == ch; } } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SpaceAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SpaceAction.java new file mode 100644 index 00000000..d737680d --- /dev/null +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SpaceAction.java @@ -0,0 +1,28 @@ +package com.sum.spirit.core.lexer.action; + +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import com.sum.spirit.core.api.LexerAction; +import com.sum.spirit.core.lexer.entity.CharEvent; +import com.sum.spirit.core.lexer.entity.LexerContext; +import com.sum.spirit.core.lexer.entity.LexerResult; +import com.sum.spirit.core.lexer.entity.Region; +import com.sum.spirit.core.lexer.entity.LexerResult.State; + +@Component +@Order(-40) +public class SpaceAction implements LexerAction { + + @Override + public boolean isTrigger(CharEvent event) { + return event.ch == ' '; + } + + @Override + public LexerResult handle(CharEvent event) { + LexerContext context = (LexerContext) event.context; + return new LexerResult(State.SKIP, new Region(context.index, context.index + 1)); + } + +} diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java index 33ab6ae0..6b71b27c 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java @@ -4,25 +4,24 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.SymbolEnum; +import com.sum.spirit.core.api.LexerAction; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; +import com.sum.spirit.core.lexer.entity.LexerResult; import com.sum.spirit.core.lexer.entity.Region; +import com.sum.spirit.core.lexer.entity.LexerResult.State; @Component -@Order(-80) -public class SymbolAction extends AbstractLexerAction { +@Order(-60) +public class SymbolAction implements LexerAction { @Override public boolean isTrigger(CharEvent event) { return SymbolEnum.isSymbolChar(event.ch); } - /** - * -尝试拆分双字符和单字符符号 - */ @Override - public void handle(CharEvent event) { - + public LexerResult handle(CharEvent event) { LexerContext context = (LexerContext) event.context; StringBuilder builder = context.builder; @@ -30,16 +29,15 @@ public class SymbolAction extends AbstractLexerAction { String str = builder.substring(context.index, context.index + 2); if (SymbolEnum.isDoubleSymbol(str)) { Region region = new Region(context.index, context.index + 2); - replaceRegion(builder, region, "@symbol" + context.nameCount++, context.replacedStrs); - return; + context.index++;// 符合条件,则跳过一个单位 + return new LexerResult(State.SKIP, region); } } String str = builder.substring(context.index, context.index + 1); if (SymbolEnum.isSingleSymbol(str)) { Region region = new Region(context.index, context.index + 1); - replaceRegion(builder, region, "@symbol" + context.nameCount++, context.replacedStrs); - return; + return new LexerResult(State.SKIP, region); } throw new RuntimeException("Unable to process symbol!"); diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerContext.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerContext.java index 5731cfa7..77fa55ea 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerContext.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerContext.java @@ -1,27 +1,29 @@ package com.sum.spirit.core.lexer.entity; +import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; -import lombok.NonNull; @NoArgsConstructor @AllArgsConstructor public class LexerContext extends CharsContext { - public List splitChars; - public int nameCount; - @NonNull - public Map replacedStrs = new HashMap<>(); public int startIndex = -1; + public List regions = new ArrayList<>(); + public String profile; + public List splitChars; public List words; - public LexerContext(StringBuilder builder, Character... splitChars) { + public LexerContext(StringBuilder builder) { + this.builder = builder; + } + + public LexerContext(StringBuilder builder, String profile, Character... splitChars) { this.builder = builder; + this.profile = profile; this.splitChars = Arrays.asList(splitChars); } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java new file mode 100644 index 00000000..f738734d --- /dev/null +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java @@ -0,0 +1,18 @@ +package com.sum.spirit.core.lexer.entity; + +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +@AllArgsConstructor +public class LexerResult { + + public enum State { + TRY, SKIP + } + + public State state; + + public Region region; + +} diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/Region.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/Region.java index 1e63f5f1..8b95018f 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/Region.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/Region.java @@ -16,4 +16,8 @@ public class Region { return endIndex - startIndex; } + public boolean contains(int index) { + return startIndex <= index && index < endIndex; + } + } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/utils/RegionUtils.java similarity index 35% rename from spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java rename to spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/utils/RegionUtils.java index 0bc1b948..8ef622e0 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/AbstractLexerAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/utils/RegionUtils.java @@ -1,49 +1,71 @@ -package com.sum.spirit.core.lexer.action; +package com.sum.spirit.core.lexer.utils; +import java.util.ArrayList; import java.util.List; -import java.util.Map; import org.apache.commons.lang3.StringUtils; import com.sum.spirit.common.utils.LineUtils; import com.sum.spirit.common.utils.ListUtils; -import com.sum.spirit.core.api.CharAction; import com.sum.spirit.core.lexer.entity.Region; import cn.hutool.core.lang.Assert; -public abstract class AbstractLexerAction implements CharAction { +public class RegionUtils { - public Region findRegion(StringBuilder builder, int fromIndex, char leftChar, char rightChar) { + public static Region findRegion(StringBuilder builder, int fromIndex, char leftChar, char rightChar) { int endIndex = LineUtils.findEndIndex(builder, fromIndex, leftChar, rightChar); return endIndex != -1 ? new Region(fromIndex, endIndex + 1) : null; } - public String subRegion(StringBuilder builder, Region region) { + public static String subRegion(StringBuilder builder, Region region) { return builder.substring(region.startIndex, region.endIndex); } - public Region mergeRegions(List regions) { + public static Region mergeRegions(List regions) { Assert.notEmpty(regions, "The regions cannot be empty!"); Region startRegion = ListUtils.findOneByScore(regions, region -> 0 - region.startIndex); Region endRegion = ListUtils.findOneByScore(regions, region -> region.endIndex); return new Region(startRegion.startIndex, endRegion.endIndex); } - public String replaceRegion(StringBuilder builder, Region region, String markName) { - if (region == null) { - return null; + public static List completeRegions(StringBuilder builder, List regions, Consumer consumer) { + List newRegions = new ArrayList<>(); + int lastIndex = 0; + for (Region region : regions) { + if (region.startIndex > lastIndex) { + Region newRegion = new Region(lastIndex, region.startIndex); + newRegions.add(newRegion); + consumer.accept(newRegion); + } + newRegions.add(region); + lastIndex = region.endIndex; } - String content = builder.substring(region.startIndex, region.endIndex); - builder.replace(region.startIndex, region.endIndex, " " + markName + " "); - return content; + if (lastIndex < builder.length()) { + Region newRegion = new Region(lastIndex, builder.length()); + newRegions.add(newRegion); + consumer.accept(newRegion); + } + return newRegions; } - public void replaceRegion(StringBuilder builder, Region region, String markName, Map replacedStrs) { - String content = replaceRegion(builder, region, markName); - if (StringUtils.isNotBlank(content) && replacedStrs != null) { - replacedStrs.put(markName, content); + public static List subRegions(StringBuilder builder, List regions, Consumer0 consumer) { + List words = new ArrayList<>(); + for (Region region : regions) { + String text = subRegion(builder, region); + if (StringUtils.isNotBlank(text)) { + consumer.accept(words, region, text.trim()); + } } + return words; + } + + public static interface Consumer { + void accept(T t); + } + + public static interface Consumer0 { + void accept(List words, T t, String text); } } diff --git a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java index bf9ca255..f9e9c5ce 100644 --- a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java +++ b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java @@ -335,4 +335,50 @@ public class LexerTest { assertEquals(words.get(count++), ")"); } + @Test + @DisplayName("MY_TEST") + public void test0022() { + String text = "xxxxG_Alias=\"Clock moved backwards.G_Alias to generate id for %d milliseconds\""; + List words = lexer.getWords(text); + log.info(words.toString()); + assertTrue(words.size() == 3); + int count = 0; + assertEquals(words.get(count++), "xxxxG_Alias"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "\"Clock moved backwards.G_Alias to generate id for %d milliseconds\""); + } + + @Test + @DisplayName("MY_TEST1") + public void test0023() { + String text = "if s==\"hello\"{"; + List words = lexer.getWords(text); + log.info(words.toString()); + assertTrue(words.size() == 5); + int count = 0; + assertEquals(words.get(count++), "if"); + assertEquals(words.get(count++), "s"); + assertEquals(words.get(count++), "=="); + assertEquals(words.get(count++), "\"hello\""); + assertEquals(words.get(count++), "{"); + } + + @Test + @DisplayName("MY_TEST2") + public void test0024() { + String text = "b=father.child.father.child.father.name"; + List words = lexer.getWords(text); + log.info(words.toString()); + assertTrue(words.size() == 8); + int count = 0; + assertEquals(words.get(count++), "b"); + assertEquals(words.get(count++), "="); + assertEquals(words.get(count++), "father"); + assertEquals(words.get(count++), ".child"); + assertEquals(words.get(count++), ".father"); + assertEquals(words.get(count++), ".child"); + assertEquals(words.get(count++), ".father"); + assertEquals(words.get(count++), ".name"); + } + } -- Gitee From 9233e59e1b227ef82268f48c622db1497087f631 Mon Sep 17 00:00:00 2001 From: chenT Date: Fri, 30 Apr 2021 21:39:25 +0800 Subject: [PATCH 088/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/core/lexer/entity/LexerResult.java | 1 - 1 file changed, 1 deletion(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java index f738734d..2068fb2f 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java @@ -12,7 +12,6 @@ public class LexerResult { } public State state; - public Region region; } -- Gitee From d429cfd4d933133046ab838eff78b6fe921369ff Mon Sep 17 00:00:00 2001 From: chenT Date: Fri, 30 Apr 2021 22:52:53 +0800 Subject: [PATCH 089/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/lexer/AbstractCursorLexer.java | 2 +- .../lexer/{AbstractLexer.java => AbstractRegionLexer.java} | 6 +++--- .../java/com/sum/spirit/core/lexer/action/BorderAction.java | 2 +- .../java/com/sum/spirit/core/lexer/action/RegionAction.java | 2 +- .../java/com/sum/spirit/core/lexer/action/SpaceAction.java | 2 +- .../java/com/sum/spirit/core/lexer/action/SymbolAction.java | 4 ++-- .../java/com/sum/spirit/core/lexer/entity/LexerResult.java | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) rename spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/{AbstractLexer.java => AbstractRegionLexer.java} (93%) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCursorLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCursorLexer.java index b7bb00f4..a10e5d85 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCursorLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCursorLexer.java @@ -4,7 +4,7 @@ import com.sum.spirit.common.utils.LineUtils; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; -public abstract class AbstractCursorLexer extends AbstractLexer { +public abstract class AbstractCursorLexer extends AbstractRegionLexer { @Override public void handle(CharEvent event) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractRegionLexer.java similarity index 93% rename from spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java rename to spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractRegionLexer.java index 19dff636..b6a35d71 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractRegionLexer.java @@ -19,7 +19,7 @@ import com.sum.spirit.core.lexer.entity.Region; import com.sum.spirit.core.lexer.utils.RegionUtils; import com.sum.spirit.core.lexer.entity.LexerResult.State; -public abstract class AbstractLexer extends AbstractCharsHandler implements Lexer { +public abstract class AbstractRegionLexer extends AbstractCharsHandler implements Lexer { @Autowired public List actions; @@ -67,9 +67,9 @@ public abstract class AbstractLexer extends AbstractCharsHandler implements Lexe LexerContext context = (LexerContext) event.context; context.regions.add(result.region); } - if (result.state == State.TRY) { + if (result.state == State.CONTINUE) { continue; - } else if (result.state == State.SKIP) { + } else if (result.state == State.BREAK) { break; } } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java index c636eafe..53d379a2 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java @@ -43,7 +43,7 @@ public class BorderAction extends RegionAction { context.words = Splitter.splitByIndexsTrimRemain(builder.toString(), indexs); context.index = builder.length(); - return new LexerResult(State.SKIP, null); + return new LexerResult(State.BREAK, null); } } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java index 7087bfa6..5e18076d 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java @@ -97,7 +97,7 @@ public class RegionAction implements LexerAction { LexerContext context = (LexerContext) event.context; Region mergedRegion = RegionUtils.mergeRegions(regions); context.index = mergedRegion.endIndex - 1; - return new LexerResult(State.SKIP, mergedRegion); + return new LexerResult(State.BREAK, mergedRegion); } public boolean isCharAt(StringBuilder builder, int index, char ch) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SpaceAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SpaceAction.java index d737680d..4a68a104 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SpaceAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SpaceAction.java @@ -22,7 +22,7 @@ public class SpaceAction implements LexerAction { @Override public LexerResult handle(CharEvent event) { LexerContext context = (LexerContext) event.context; - return new LexerResult(State.SKIP, new Region(context.index, context.index + 1)); + return new LexerResult(State.BREAK, new Region(context.index, context.index + 1)); } } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java index 6b71b27c..ed9828c4 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java @@ -30,14 +30,14 @@ public class SymbolAction implements LexerAction { if (SymbolEnum.isDoubleSymbol(str)) { Region region = new Region(context.index, context.index + 2); context.index++;// 符合条件,则跳过一个单位 - return new LexerResult(State.SKIP, region); + return new LexerResult(State.BREAK, region); } } String str = builder.substring(context.index, context.index + 1); if (SymbolEnum.isSingleSymbol(str)) { Region region = new Region(context.index, context.index + 1); - return new LexerResult(State.SKIP, region); + return new LexerResult(State.BREAK, region); } throw new RuntimeException("Unable to process symbol!"); diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java index 2068fb2f..5b2a1269 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java @@ -8,7 +8,7 @@ import lombok.NoArgsConstructor; public class LexerResult { public enum State { - TRY, SKIP + CONTINUE, BREAK } public State state; -- Gitee From 4381dedc009f409057ba2f0f60fb4dec2421cd5e Mon Sep 17 00:00:00 2001 From: chenT Date: Sat, 1 May 2021 00:38:07 +0800 Subject: [PATCH 090/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/common/utils/Splitter.java | 28 ------------------- .../core/lexer/AbstractRegionLexer.java | 10 +++---- .../core/lexer/action/BorderAction.java | 13 +++++---- .../spirit/core/lexer/utils/RegionUtils.java | 12 ++++++-- .../sum/spirit/core/lexer/test/LexerTest.java | 18 ++++++++++++ 5 files changed, 40 insertions(+), 41 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java index fd09ebbb..a70f1684 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/Splitter.java @@ -3,38 +3,10 @@ package com.sum.spirit.common.utils; import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang3.StringUtils; - import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; public class Splitter { - public static List splitByIndexsTrimRemain(String str, List indexs) { - Assert.isTrue(indexs != null && indexs.size() > 0, "indexs cannot be empty!"); - List strs = new ArrayList<>(); - int lastIndex = 0; - for (Integer index : indexs) { - if (index >= lastIndex) { - if (index > lastIndex) { - addIfNotBlank(strs, str.substring(lastIndex, index)); - } - addIfNotBlank(strs, str.substring(index, index + 1)); - } - lastIndex = index + 1; - } - if (lastIndex != str.length()) { - addIfNotBlank(strs, str.substring(lastIndex, str.length())); - } - return strs; - } - - public static void addIfNotBlank(List strs, String str) { - if (StringUtils.isNotBlank(str)) { - strs.add(str); - } - } - public static List> splitByMatcherTrim(List list, Matcher matcher) { int[] indexs = CollUtil.indexOfAll(list, item -> matcher.accept(item)); List> subLists = new ArrayList<>(); diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractRegionLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractRegionLexer.java index b6a35d71..9edc4b29 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractRegionLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractRegionLexer.java @@ -32,12 +32,10 @@ public abstract class AbstractRegionLexer extends AbstractCharsHandler implement public void completeRegions(CharsContext context, StringBuilder builder) { LexerContext lexerContext = (LexerContext) context; - if (lexerContext.words == null) { - List regions = lexerContext.regions; - Set completedRegions = new HashSet(); - regions = RegionUtils.completeRegions(builder, regions, region -> completedRegions.add(region)); - lexerContext.words = RegionUtils.subRegions(builder, regions, (words, region, text) -> addToWords(words, completedRegions, region, text)); - } + List regions = lexerContext.regions; + Set completedRegions = new HashSet(); + regions = RegionUtils.completeRegions(builder, regions, region -> completedRegions.add(region)); + lexerContext.words = RegionUtils.subRegions(builder, regions, (words, region, text) -> addToWords(words, completedRegions, region, text)); } public void addToWords(List words, Set completedRegions, Region region, String text) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java index 53d379a2..edc18f58 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java @@ -6,11 +6,11 @@ import java.util.List; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import com.sum.spirit.common.utils.Splitter; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; import com.sum.spirit.core.lexer.entity.LexerResult; import com.sum.spirit.core.lexer.entity.Region; +import com.sum.spirit.core.lexer.utils.RegionUtils; import com.sum.spirit.core.lexer.entity.LexerResult.State; @Component @@ -31,17 +31,20 @@ public class BorderAction extends RegionAction { StringBuilder builder = context.builder; List splitChars = context.splitChars; - List indexs = new ArrayList<>(); + List newRegions = new ArrayList<>(); for (Region region : regions) { char startChar = builder.charAt(region.startIndex); char endChar = builder.charAt(region.endIndex - 1); if (splitChars.contains(startChar) && splitChars.contains(endChar)) { - indexs.add(region.startIndex); - indexs.add(region.endIndex - 1); + newRegions.add(new Region(region.startIndex, region.startIndex + 1)); + if (region.endIndex - region.startIndex > 1) { + newRegions.add(new Region(region.startIndex + 1, region.endIndex - 1)); + } + newRegions.add(new Region(region.endIndex - 1, region.endIndex)); } } - context.words = Splitter.splitByIndexsTrimRemain(builder.toString(), indexs); + context.regions = RegionUtils.completeRegions(builder, newRegions); context.index = builder.length(); return new LexerResult(State.BREAK, null); } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/utils/RegionUtils.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/utils/RegionUtils.java index 8ef622e0..856169ed 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/utils/RegionUtils.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/utils/RegionUtils.java @@ -36,7 +36,9 @@ public class RegionUtils { if (region.startIndex > lastIndex) { Region newRegion = new Region(lastIndex, region.startIndex); newRegions.add(newRegion); - consumer.accept(newRegion); + if (consumer != null) { + consumer.accept(newRegion); + } } newRegions.add(region); lastIndex = region.endIndex; @@ -44,11 +46,17 @@ public class RegionUtils { if (lastIndex < builder.length()) { Region newRegion = new Region(lastIndex, builder.length()); newRegions.add(newRegion); - consumer.accept(newRegion); + if (consumer != null) { + consumer.accept(newRegion); + } } return newRegions; } + public static List completeRegions(StringBuilder builder, List regions) { + return completeRegions(builder, regions, null); + } + public static List subRegions(StringBuilder builder, List regions, Consumer0 consumer) { List words = new ArrayList<>(); for (Region region : regions) { diff --git a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java index f9e9c5ce..206b46d1 100644 --- a/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java +++ b/spirit-core/spirit-core-lexer/src/test/java/com/sum/spirit/core/lexer/test/LexerTest.java @@ -381,4 +381,22 @@ public class LexerTest { assertEquals(words.get(count++), ".name"); } + @Test + @DisplayName("MY_TEST3") + public void test0025() { + String text = ".format(\"Clock moved backwards.Refusing to generate id for %d milliseconds\", lastTimestamp - timestamp)"; + List words = lexer.getSubWords(text, '(', ')', '[', ']', '{', '}'); + log.info(words.toString()); + assertTrue(words.size() == 8); + int count = 0; + assertEquals(words.get(count++), ".format"); + assertEquals(words.get(count++), "("); + assertEquals(words.get(count++), "\"Clock moved backwards.Refusing to generate id for %d milliseconds\""); + assertEquals(words.get(count++), ","); + assertEquals(words.get(count++), "lastTimestamp"); + assertEquals(words.get(count++), "-"); + assertEquals(words.get(count++), "timestamp"); + assertEquals(words.get(count++), ")"); + } + } -- Gitee From 8940469717238358c65c8f875baada54a7a3642b Mon Sep 17 00:00:00 2001 From: chenT Date: Sat, 1 May 2021 00:42:52 +0800 Subject: [PATCH 091/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/lexer/action/BorderAction.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java index edc18f58..54d2838f 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java @@ -37,9 +37,6 @@ public class BorderAction extends RegionAction { char endChar = builder.charAt(region.endIndex - 1); if (splitChars.contains(startChar) && splitChars.contains(endChar)) { newRegions.add(new Region(region.startIndex, region.startIndex + 1)); - if (region.endIndex - region.startIndex > 1) { - newRegions.add(new Region(region.startIndex + 1, region.endIndex - 1)); - } newRegions.add(new Region(region.endIndex - 1, region.endIndex)); } } -- Gitee From ee030ae1f85655f7e91a87365130a97481744e4d Mon Sep 17 00:00:00 2001 From: chenT Date: Tue, 4 May 2021 23:06:07 +0800 Subject: [PATCH 092/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/lexer/AbstractCursorLexer.java | 2 +- .../core/lexer/{AbstractRegionLexer.java => AbstractLexer.java} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/{AbstractRegionLexer.java => AbstractLexer.java} (96%) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCursorLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCursorLexer.java index a10e5d85..b7bb00f4 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCursorLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCursorLexer.java @@ -4,7 +4,7 @@ import com.sum.spirit.common.utils.LineUtils; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; -public abstract class AbstractCursorLexer extends AbstractRegionLexer { +public abstract class AbstractCursorLexer extends AbstractLexer { @Override public void handle(CharEvent event) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractRegionLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java similarity index 96% rename from spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractRegionLexer.java rename to spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java index 9edc4b29..1f6ae458 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractRegionLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java @@ -19,7 +19,7 @@ import com.sum.spirit.core.lexer.entity.Region; import com.sum.spirit.core.lexer.utils.RegionUtils; import com.sum.spirit.core.lexer.entity.LexerResult.State; -public abstract class AbstractRegionLexer extends AbstractCharsHandler implements Lexer { +public abstract class AbstractLexer extends AbstractCharsHandler implements Lexer { @Autowired public List actions; -- Gitee From 640578ec1b21f460f46e91ed542f1b0724195961 Mon Sep 17 00:00:00 2001 From: chenT Date: Tue, 4 May 2021 23:09:42 +0800 Subject: [PATCH 093/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java index 1f6ae458..87a68067 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java @@ -33,7 +33,7 @@ public abstract class AbstractLexer extends AbstractCharsHandler implements Lexe public void completeRegions(CharsContext context, StringBuilder builder) { LexerContext lexerContext = (LexerContext) context; List regions = lexerContext.regions; - Set completedRegions = new HashSet(); + Set completedRegions = new HashSet<>(); regions = RegionUtils.completeRegions(builder, regions, region -> completedRegions.add(region)); lexerContext.words = RegionUtils.subRegions(builder, regions, (words, region, text) -> addToWords(words, completedRegions, region, text)); } -- Gitee From d9da9537c94b1d82075ecfbafe83b8bc99639024 Mon Sep 17 00:00:00 2001 From: chenT Date: Tue, 4 May 2021 23:59:48 +0800 Subject: [PATCH 094/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/core/lexer/AbstractLexer.java | 18 ++++----- .../core/lexer/action/BorderAction.java | 2 +- .../spirit/core/lexer/utils/RegionUtils.java | 40 +++++++++---------- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java index 87a68067..7d2da830 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java @@ -1,9 +1,7 @@ package com.sum.spirit.core.lexer; import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; @@ -17,6 +15,7 @@ import com.sum.spirit.core.lexer.entity.LexerContext; import com.sum.spirit.core.lexer.entity.LexerResult; import com.sum.spirit.core.lexer.entity.Region; import com.sum.spirit.core.lexer.utils.RegionUtils; +import com.sum.spirit.core.lexer.utils.RegionUtils.completedRegion; import com.sum.spirit.core.lexer.entity.LexerResult.State; public abstract class AbstractLexer extends AbstractCharsHandler implements Lexer { @@ -33,22 +32,19 @@ public abstract class AbstractLexer extends AbstractCharsHandler implements Lexe public void completeRegions(CharsContext context, StringBuilder builder) { LexerContext lexerContext = (LexerContext) context; List regions = lexerContext.regions; - Set completedRegions = new HashSet<>(); - regions = RegionUtils.completeRegions(builder, regions, region -> completedRegions.add(region)); - lexerContext.words = RegionUtils.subRegions(builder, regions, (words, region, text) -> addToWords(words, completedRegions, region, text)); + regions = RegionUtils.completeRegions(builder, regions); + lexerContext.words = RegionUtils.subRegions(builder, regions, this::addToWords); } - public void addToWords(List words, Set completedRegions, Region region, String text) { - if (completedRegions.contains(region)) { + public void addToWords(List words, Region region, String text) { + if (region instanceof completedRegion) { if (text.indexOf(".") > 0 && !LiteralEnum.isDouble(text) && !TypeEnum.isTypeEnd(text)) { List subWords = Arrays.asList(text.replaceAll("\\.", " .").split(" ")); words.addAll(subWords); - } else { - words.add(text); + return; } - } else { - words.add(text); } + words.add(text); } @Override diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java index 54d2838f..05031f0a 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/BorderAction.java @@ -41,7 +41,7 @@ public class BorderAction extends RegionAction { } } - context.regions = RegionUtils.completeRegions(builder, newRegions); + context.regions = RegionUtils.completeRegions(builder, newRegions, (startIndex, endIndex) -> new Region(startIndex, endIndex)); context.index = builder.length(); return new LexerResult(State.BREAK, null); } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/utils/RegionUtils.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/utils/RegionUtils.java index 856169ed..fecd72ba 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/utils/RegionUtils.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/utils/RegionUtils.java @@ -29,35 +29,29 @@ public class RegionUtils { return new Region(startRegion.startIndex, endRegion.endIndex); } - public static List completeRegions(StringBuilder builder, List regions, Consumer consumer) { - List newRegions = new ArrayList<>(); + public static List completeRegions(StringBuilder builder, List regions, Factory factory) { + List completedRegions = new ArrayList<>(); int lastIndex = 0; for (Region region : regions) { if (region.startIndex > lastIndex) { - Region newRegion = new Region(lastIndex, region.startIndex); - newRegions.add(newRegion); - if (consumer != null) { - consumer.accept(newRegion); - } + Region newRegion = factory.newRegion(lastIndex, region.startIndex); + completedRegions.add(newRegion); } - newRegions.add(region); + completedRegions.add(region); lastIndex = region.endIndex; } if (lastIndex < builder.length()) { - Region newRegion = new Region(lastIndex, builder.length()); - newRegions.add(newRegion); - if (consumer != null) { - consumer.accept(newRegion); - } + Region newRegion = factory.newRegion(lastIndex, builder.length()); + completedRegions.add(newRegion); } - return newRegions; + return completedRegions; } public static List completeRegions(StringBuilder builder, List regions) { - return completeRegions(builder, regions, null); + return completeRegions(builder, regions, (startIndex, endIndex) -> new completedRegion(startIndex, endIndex)); } - public static List subRegions(StringBuilder builder, List regions, Consumer0 consumer) { + public static List subRegions(StringBuilder builder, List regions, Consumer consumer) { List words = new ArrayList<>(); for (Region region : regions) { String text = subRegion(builder, region); @@ -68,12 +62,18 @@ public class RegionUtils { return words; } - public static interface Consumer { - void accept(T t); + public static interface Factory { + Region newRegion(int startIndex, int endIndex); + } + + public static interface Consumer { + void accept(List words, Region region, String text); } - public static interface Consumer0 { - void accept(List words, T t, String text); + public static class completedRegion extends Region { + public completedRegion(int startIndex, int endIndex) { + super(startIndex, endIndex); + } } } -- Gitee From f50c52fb339ffc8a87df99b3b961151eae00fbf7 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 00:01:29 +0800 Subject: [PATCH 095/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java index 7d2da830..c35d8237 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java @@ -31,8 +31,7 @@ public abstract class AbstractLexer extends AbstractCharsHandler implements Lexe public void completeRegions(CharsContext context, StringBuilder builder) { LexerContext lexerContext = (LexerContext) context; - List regions = lexerContext.regions; - regions = RegionUtils.completeRegions(builder, regions); + List regions = RegionUtils.completeRegions(builder, lexerContext.regions); lexerContext.words = RegionUtils.subRegions(builder, regions, this::addToWords); } -- Gitee From 8b4fe6268806aa1fa9b6e582a9b42f41d003bc3e Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 11:43:39 +0800 Subject: [PATCH 096/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/api/CharsHandler.java | 3 ++- .../sum/spirit/core/lexer/AbstractCharsHandler.java | 9 ++++++++- .../com/sum/spirit/core/lexer/AbstractLexer.java | 13 +++++-------- .../sum/spirit/core/lexer/AliasCharsHandler.java | 12 +++++++----- .../java/com/sum/spirit/core/lexer/CoreLexer.java | 13 ++++++++----- .../sum/spirit/core/lexer/entity/CharsResult.java | 12 ++++++++++++ .../sum/spirit/core/lexer/entity/LexerContext.java | 1 - 7 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/CharsResult.java diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/CharsHandler.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/CharsHandler.java index b31e4be6..92ce39d9 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/CharsHandler.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/api/CharsHandler.java @@ -1,9 +1,10 @@ package com.sum.spirit.core.api; import com.sum.spirit.core.lexer.entity.CharsContext; +import com.sum.spirit.core.lexer.entity.CharsResult; public interface CharsHandler { - void handle(CharsContext context, StringBuilder builder); + CharsResult handle(CharsContext context, StringBuilder builder); } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCharsHandler.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCharsHandler.java index 59bc6c75..890b1aed 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCharsHandler.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractCharsHandler.java @@ -4,11 +4,12 @@ import com.sum.spirit.core.api.CharAction; import com.sum.spirit.core.api.CharsHandler; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.CharsContext; +import com.sum.spirit.core.lexer.entity.CharsResult; public abstract class AbstractCharsHandler implements CharsHandler, CharAction { @Override - public void handle(CharsContext context, StringBuilder builder) { + public CharsResult handle(CharsContext context, StringBuilder builder) { for (; context.index < builder.length(); context.index++) { char ch = builder.charAt(context.index); CharEvent event = new CharEvent(context, ch); @@ -16,6 +17,12 @@ public abstract class AbstractCharsHandler implements CharsHandler, CharAction { this.handle(event); } } + return buildResult(context, builder); + + } + + public CharsResult buildResult(CharsContext context, StringBuilder builder) { + return new CharsResult(builder); } } diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java index c35d8237..8bd902b7 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java @@ -11,6 +11,7 @@ import com.sum.spirit.core.api.Lexer; import com.sum.spirit.core.api.LexerAction; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.CharsContext; +import com.sum.spirit.core.lexer.entity.CharsResult; import com.sum.spirit.core.lexer.entity.LexerContext; import com.sum.spirit.core.lexer.entity.LexerResult; import com.sum.spirit.core.lexer.entity.Region; @@ -24,15 +25,11 @@ public abstract class AbstractLexer extends AbstractCharsHandler implements Lexe public List actions; @Override - public void handle(CharsContext context, StringBuilder builder) { - super.handle(context, builder); - completeRegions(context, builder);// 使用标记收集算法后,补全未标记的部分 - } - - public void completeRegions(CharsContext context, StringBuilder builder) { + public CharsResult buildResult(CharsContext context, StringBuilder builder) { LexerContext lexerContext = (LexerContext) context; - List regions = RegionUtils.completeRegions(builder, lexerContext.regions); - lexerContext.words = RegionUtils.subRegions(builder, regions, this::addToWords); + List regions = RegionUtils.completeRegions(builder, lexerContext.regions);// 使用标记收集算法后,补全未标记的部分 + List words = RegionUtils.subRegions(builder, regions, this::addToWords); + return new CharsResult(words); } public void addToWords(List words, Region region, String text) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java index 2c11316c..878926cd 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java @@ -5,6 +5,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.utils.LineUtils; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.CharsContext; +import com.sum.spirit.core.lexer.entity.CharsResult; @Component public class AliasCharsHandler extends AbstractCharsHandler { @@ -19,11 +20,13 @@ public class AliasCharsHandler extends AbstractCharsHandler { */ public String replace(String code, String alias, String className) { AliasCharsContext context = new AliasCharsContext(); - context.builder = new StringBuilder(code); + StringBuilder builder = new StringBuilder(code); + context.builder = builder; context.alias = alias; context.className = className; - handle(context, context.builder); - return context.builder.toString(); + CharsResult result = handle(context, builder); + builder = (StringBuilder) result.payload; + return builder.toString(); } /** @@ -44,8 +47,7 @@ public class AliasCharsHandler extends AbstractCharsHandler { } /** - * -根据alias的宽度,截取一段字符串,如果相等,则进行替换 - * -注意:这段字符串的前后,不能是连续的字符 + * -根据alias的宽度,截取一段字符串,如果相等,则进行替换 -注意:这段字符串的前后,不能是连续的字符 */ @Override public void handle(CharEvent event) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java index 75160145..3870b871 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/CoreLexer.java @@ -6,6 +6,7 @@ import java.util.List; import org.springframework.stereotype.Component; import com.sum.spirit.core.lexer.action.BorderAction; +import com.sum.spirit.core.lexer.entity.CharsResult; import com.sum.spirit.core.lexer.entity.LexerContext; import cn.hutool.core.lang.Assert; @@ -14,23 +15,25 @@ import cn.hutool.core.lang.Assert; public class CoreLexer extends AbstractCursorLexer { @Override + @SuppressWarnings("unchecked") public List getWords(String text) { Assert.notBlank(text, "Text cannot be blank!"); StringBuilder builder = new StringBuilder(text.trim()); LexerContext context = new LexerContext(builder); - handle(context, builder); - return context.words; + CharsResult result = handle(context, builder); + return (List) result.payload; } @Override + @SuppressWarnings("unchecked") public List getSubWords(String text, Character... splitChars) { Assert.notBlank(text, "Text cannot be blank!"); StringBuilder builder = new StringBuilder(text.trim()); LexerContext context = new LexerContext(builder, BorderAction.PROFILE, splitChars); - handle(context, builder); - Assert.notNull(context.words, "Words of context cannot be null!"); + CharsResult result = handle(context, builder); + Assert.notNull(result.payload, "Payload of result cannot be null!"); List words = new ArrayList<>(); - for (String word : context.words) { + for (String word : (List) result.payload) { if (word.length() == 1) { words.add(word); } else { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/CharsResult.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/CharsResult.java new file mode 100644 index 00000000..99405d86 --- /dev/null +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/CharsResult.java @@ -0,0 +1,12 @@ +package com.sum.spirit.core.lexer.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class CharsResult { + public Object payload; +} diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerContext.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerContext.java index 77fa55ea..d81588eb 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerContext.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerContext.java @@ -15,7 +15,6 @@ public class LexerContext extends CharsContext { public List regions = new ArrayList<>(); public String profile; public List splitChars; - public List words; public LexerContext(StringBuilder builder) { this.builder = builder; -- Gitee From 961f3ba5d4a67a4dcd432c84d8f666320035d9f6 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 11:48:31 +0800 Subject: [PATCH 097/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/lexer/action/SymbolAction.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java index ed9828c4..510628c5 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java @@ -34,8 +34,8 @@ public class SymbolAction implements LexerAction { } } - String str = builder.substring(context.index, context.index + 1); - if (SymbolEnum.isSingleSymbol(str)) { + String text = builder.substring(context.index, context.index + 1); + if (SymbolEnum.isSingleSymbol(text)) { Region region = new Region(context.index, context.index + 1); return new LexerResult(State.BREAK, region); } -- Gitee From acd945e0d1d88d298a89689c01321a6bc79be4db Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 11:49:22 +0800 Subject: [PATCH 098/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/lexer/action/SymbolAction.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java index 510628c5..ed9828c4 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java @@ -34,8 +34,8 @@ public class SymbolAction implements LexerAction { } } - String text = builder.substring(context.index, context.index + 1); - if (SymbolEnum.isSingleSymbol(text)) { + String str = builder.substring(context.index, context.index + 1); + if (SymbolEnum.isSingleSymbol(str)) { Region region = new Region(context.index, context.index + 1); return new LexerResult(State.BREAK, region); } -- Gitee From db90eda8be3d84c0ede97cbf4507e393ea513036 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 12:18:01 +0800 Subject: [PATCH 099/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/UnhandledException.java | 26 +++++++++++++++++++ .../spirit/core/lexer/AliasCharsHandler.java | 14 ---------- .../core/lexer/action/RegionAction.java | 3 ++- .../core/lexer/action/SymbolAction.java | 3 ++- 4 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 spirit-common/src/main/java/com/sum/spirit/common/exception/UnhandledException.java diff --git a/spirit-common/src/main/java/com/sum/spirit/common/exception/UnhandledException.java b/spirit-common/src/main/java/com/sum/spirit/common/exception/UnhandledException.java new file mode 100644 index 00000000..b839a02b --- /dev/null +++ b/spirit-common/src/main/java/com/sum/spirit/common/exception/UnhandledException.java @@ -0,0 +1,26 @@ +package com.sum.spirit.common.exception; + +@SuppressWarnings("serial") +public class UnhandledException extends RuntimeException { + + public UnhandledException() { + super(); + } + + public UnhandledException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public UnhandledException(String message, Throwable cause) { + super(message, cause); + } + + public UnhandledException(String message) { + super(message); + } + + public UnhandledException(Throwable cause) { + super(cause); + } + +} diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java index 878926cd..1d02911c 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AliasCharsHandler.java @@ -10,14 +10,6 @@ import com.sum.spirit.core.lexer.entity.CharsResult; @Component public class AliasCharsHandler extends AbstractCharsHandler { - /** - * -将别名替换为完整的类名 - * - * @param code - * @param alias - * @param className - * @return - */ public String replace(String code, String alias, String className) { AliasCharsContext context = new AliasCharsContext(); StringBuilder builder = new StringBuilder(code); @@ -29,9 +21,6 @@ public class AliasCharsHandler extends AbstractCharsHandler { return builder.toString(); } - /** - * -遇到字符串,则跳过,如果当前字符和别名的别名的首字母相同,则触发处理逻辑 - */ @Override public boolean isTrigger(CharEvent event) { AliasCharsContext context = (AliasCharsContext) event.context; @@ -46,9 +35,6 @@ public class AliasCharsHandler extends AbstractCharsHandler { return false; } - /** - * -根据alias的宽度,截取一段字符串,如果相等,则进行替换 -注意:这段字符串的前后,不能是连续的字符 - */ @Override public void handle(CharEvent event) { AliasCharsContext context = (AliasCharsContext) event.context; diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java index 5e18076d..eb821aaf 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java @@ -6,6 +6,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.TypeEnum; +import com.sum.spirit.common.exception.UnhandledException; import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.api.LexerAction; import com.sum.spirit.core.lexer.entity.CharEvent; @@ -90,7 +91,7 @@ public class RegionAction implements LexerAction { return pushStack(event, ListUtils.toListNonNull(region0, region1, region2)); } - throw new RuntimeException("Can't handle the scene!"); + throw new UnhandledException(); } public LexerResult pushStack(CharEvent event, List regions) { diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java index ed9828c4..9818575a 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/SymbolAction.java @@ -4,6 +4,7 @@ import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import com.sum.spirit.common.enums.SymbolEnum; +import com.sum.spirit.common.exception.UnhandledException; import com.sum.spirit.core.api.LexerAction; import com.sum.spirit.core.lexer.entity.CharEvent; import com.sum.spirit.core.lexer.entity.LexerContext; @@ -40,7 +41,7 @@ public class SymbolAction implements LexerAction { return new LexerResult(State.BREAK, region); } - throw new RuntimeException("Unable to process symbol!"); + throw new UnhandledException(); } } \ No newline at end of file -- Gitee From 0f62e8b2c7c59b2e27873a86d3d696c49eece49a Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 14:40:58 +0800 Subject: [PATCH 100/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/core/lexer/entity/LexerResult.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java index 5b2a1269..76ad3d79 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/entity/LexerResult.java @@ -1,8 +1,10 @@ package com.sum.spirit.core.lexer.entity; import lombok.AllArgsConstructor; +import lombok.Data; import lombok.NoArgsConstructor; +@Data @NoArgsConstructor @AllArgsConstructor public class LexerResult { -- Gitee From feffd2df320dcd31db2f1936f8c286f1f899931a Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 15:47:11 +0800 Subject: [PATCH 101/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/api/SyntaxParser.java | 21 +++++++++ .../core/element/DefaultElementBuilder.java | 31 +++++-------- ...cognizer.java => DefaultSyntaxParser.java} | 44 +++++++++---------- .../core/element/entity/SyntaxResult.java | 15 +++++++ 4 files changed, 68 insertions(+), 43 deletions(-) create mode 100644 spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SyntaxParser.java rename spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/{SyntaxRecognizer.java => DefaultSyntaxParser.java} (83%) create mode 100644 spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxResult.java diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SyntaxParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SyntaxParser.java new file mode 100644 index 00000000..0897d4c6 --- /dev/null +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SyntaxParser.java @@ -0,0 +1,21 @@ +package com.sum.spirit.core.api; + +import java.util.List; + +import com.sum.spirit.common.enums.SyntaxEnum; +import com.sum.spirit.core.element.entity.Statement; +import com.sum.spirit.core.element.entity.SyntaxResult; +import com.sum.spirit.core.element.entity.SyntaxTree; +import com.sum.spirit.core.element.entity.Token; + +public interface SyntaxParser { + + SyntaxResult parseSyntax(List tokens, Statement statement); + + SyntaxEnum getSyntaxWithoutTree(List tokens); + + SyntaxEnum getSyntaxWithTree(List tokens); + + SyntaxEnum getSyntaxByTree(SyntaxTree syntaxTree); + +} diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultElementBuilder.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultElementBuilder.java index 7c73c097..5b94675f 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultElementBuilder.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultElementBuilder.java @@ -5,17 +5,16 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.sum.spirit.common.enums.SyntaxEnum; import com.sum.spirit.core.api.ElementBuilder; import com.sum.spirit.core.api.Lexer; import com.sum.spirit.core.api.SemanticParser; +import com.sum.spirit.core.api.SyntaxParser; import com.sum.spirit.core.element.action.LineChecker; -import com.sum.spirit.core.element.action.SyntaxRecognizer; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Line; import com.sum.spirit.core.element.entity.Modifiers; import com.sum.spirit.core.element.entity.Statement; -import com.sum.spirit.core.element.entity.SyntaxTree; +import com.sum.spirit.core.element.entity.SyntaxResult; import com.sum.spirit.core.element.entity.Token; import cn.hutool.core.lang.Assert; @@ -30,7 +29,7 @@ public class DefaultElementBuilder implements ElementBuilder { @Autowired public SemanticParser parser; @Autowired - public SyntaxRecognizer recognizer; + public SyntaxParser syntaxParser; @Override public Element build(String text) { @@ -40,23 +39,13 @@ public class DefaultElementBuilder implements ElementBuilder { @Override public Element build(Line line) { try { - // 语法校验 - checker.check(line); - // 1.词法分析 - List words = lexer.getWords(line.text); - // 2.语义分析 - List tokens = parser.getTokens(words); - // 3.修饰词 - Modifiers modifiers = new Modifiers(tokens); - // 4.语句 - Statement statement = new Statement(tokens); - // 5.分析语法 - Object[] result = recognizer.parseSyntax(tokens, statement); - SyntaxEnum syntax = (SyntaxEnum) result[0]; - SyntaxTree syntaxTree = (SyntaxTree) result[1]; - // 6.创建元素 - Element element = new Element(line, modifiers, statement, syntax, syntaxTree); - // 7.返回元素 + checker.check(line); // 语法校验 + List words = lexer.getWords(line.text);// 1.词法分析 + List tokens = parser.getTokens(words);// 2.语义分析 + Modifiers modifiers = new Modifiers(tokens);// 3.修饰词 + Statement statement = new Statement(tokens);// 4.语句 + SyntaxResult result = syntaxParser.parseSyntax(tokens, statement);// 5.分析语法 + Element element = new Element(line, modifiers, statement, result.syntax, result.syntaxTree);// 6.创建元素 return element; } catch (Exception e) { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSyntaxParser.java similarity index 83% rename from spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java rename to spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSyntaxParser.java index 083d6a43..9ae50a30 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/SyntaxRecognizer.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSyntaxParser.java @@ -9,46 +9,44 @@ import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.KeywordEnum; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.SyntaxEnum; +import com.sum.spirit.core.api.SyntaxParser; import com.sum.spirit.core.api.TreeBuilder; import com.sum.spirit.core.element.entity.Node; import com.sum.spirit.core.element.entity.Statement; +import com.sum.spirit.core.element.entity.SyntaxResult; import com.sum.spirit.core.element.entity.SyntaxTree; import com.sum.spirit.core.element.entity.Token; import cn.hutool.core.lang.Assert; @Component -public class SyntaxRecognizer { +public class DefaultSyntaxParser implements SyntaxParser { @Autowired public TreeBuilder builder; - /** - * 1.能够不通过语法树获取语法,且后续功能不需要语法树 - * 2.能够不通过语法树获取语法,但后续功能需要语法树 - * 3.必须通过语法树获取语法 - * - * @param tokens - * @param statement - * @return - */ - public Object[] parseSyntax(List tokens, Statement statement) { + @Override + public SyntaxResult parseSyntax(List tokens, Statement statement) { Assert.notEmpty(tokens, "The tokens cannot be empty!"); - SyntaxEnum syntax = getSyntaxWithoutTree(tokens); - SyntaxTree syntaxTree = null; - if (syntax == null) { - syntax = getSyntaxWithTree(tokens); - if (syntax != null) { - syntaxTree = builder.buildTree(statement); - } else { - syntaxTree = builder.buildTree(statement); - syntax = getSyntaxByTree(syntaxTree); - } + + SyntaxEnum syntax = getSyntaxWithoutTree(tokens);// 1.能够不通过语法树获取语法,且后续功能不需要语法树 + if (syntax != null) { + return new SyntaxResult(syntax, null); } + + syntax = getSyntaxWithTree(tokens);// 2.能够不通过语法树获取语法,但后续功能需要语法树 + if (syntax != null) { + SyntaxTree syntaxTree = builder.buildTree(statement); + return new SyntaxResult(syntax, syntaxTree); + } + + SyntaxTree syntaxTree = builder.buildTree(statement);// 3.必须通过语法树获取语法 + syntax = getSyntaxByTree(syntaxTree); Assert.notNull(syntax, "The syntax cannot be null!"); - return new Object[] { syntax, syntaxTree }; + return new SyntaxResult(syntax, syntaxTree); } + @Override public SyntaxEnum getSyntaxWithoutTree(List tokens) { Token firstToken = tokens.get(0); Token secondToken = tokens.size() >= 2 ? tokens.get(1) : null; @@ -88,6 +86,7 @@ public class SyntaxRecognizer { return null; } + @Override public SyntaxEnum getSyntaxWithTree(List tokens) { Token firstToken = tokens.get(0); Token secondToken = tokens.size() >= 2 ? tokens.get(1) : null; @@ -128,6 +127,7 @@ public class SyntaxRecognizer { return null; } + @Override public SyntaxEnum getSyntaxByTree(SyntaxTree syntaxTree) { return syntaxTree.nodes.size() == 1 ? getSyntaxByOneNode(syntaxTree) : null; } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxResult.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxResult.java new file mode 100644 index 00000000..13ff6fa1 --- /dev/null +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SyntaxResult.java @@ -0,0 +1,15 @@ +package com.sum.spirit.core.element.entity; + +import com.sum.spirit.common.enums.SyntaxEnum; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SyntaxResult { + public SyntaxEnum syntax; + public SyntaxTree syntaxTree; +} -- Gitee From cd98228fd5dfb77301cfe2384bfdcdbe2d86417a Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 16:20:38 +0800 Subject: [PATCH 102/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LiteralPattern.java} | 15 +++-- .../TypePattern.java} | 13 ++-- .../spirit/common/pattern/VisitPattern.java | 28 +++++++++ .../action/AbstractSemanticParser.java | 63 ++++++++----------- .../sum/spirit/core/lexer/AbstractLexer.java | 6 +- .../core/lexer/action/RegionAction.java | 4 +- 6 files changed, 76 insertions(+), 53 deletions(-) rename spirit-common/src/main/java/com/sum/spirit/common/{enums/LiteralEnum.java => pattern/LiteralPattern.java} (79%) rename spirit-common/src/main/java/com/sum/spirit/common/{enums/TypeEnum.java => pattern/TypePattern.java} (89%) create mode 100644 spirit-common/src/main/java/com/sum/spirit/common/pattern/VisitPattern.java diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/LiteralEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java similarity index 79% rename from spirit-common/src/main/java/com/sum/spirit/common/enums/LiteralEnum.java rename to spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java index 188e63b4..3308830b 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/LiteralEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java @@ -1,9 +1,9 @@ -package com.sum.spirit.common.enums; +package com.sum.spirit.common.pattern; import java.util.regex.Pattern; -public enum LiteralEnum { - ; +public class LiteralPattern { + public static final Pattern NULL_PATTERN = Pattern.compile("^null$"); public static final Pattern BOOLEAN_PATTERN = Pattern.compile("^(true|false)$"); public static final Pattern CHAR_PATTERN = Pattern.compile("^'[\\s\\S]*'$"); @@ -13,8 +13,7 @@ public enum LiteralEnum { public static final Pattern STRING_PATTERN = Pattern.compile("^\"[\\s\\S]*\"$"); public static final Pattern LIST_PATTERN = Pattern.compile("^\\[[\\s\\S]*\\]$"); public static final Pattern MAP_PATTERN = Pattern.compile("^\\{[\\s\\S]*\\}$"); - - public static final Pattern VISIT_INDEX_PATTERN = Pattern.compile("^\\[\\d+\\]$"); + private static final Pattern CONST_VARIABLE_PATTERN = Pattern.compile("^[A-Z_]{2,}$");// 常量也被认为是字面值的一种 public static boolean isNull(String word) { return NULL_PATTERN.matcher(word).matches(); @@ -45,11 +44,15 @@ public enum LiteralEnum { } public static boolean isList(String word) { - return !VISIT_INDEX_PATTERN.matcher(word).matches() && LiteralEnum.LIST_PATTERN.matcher(word).matches(); + return !VisitPattern.isVisitIndex(word) && LiteralPattern.LIST_PATTERN.matcher(word).matches(); } public static boolean isMap(String word) { return MAP_PATTERN.matcher(word).matches(); } + public static boolean isConstVariable(String word) { + return CONST_VARIABLE_PATTERN.matcher(word).matches(); + } + } diff --git a/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java b/spirit-common/src/main/java/com/sum/spirit/common/pattern/TypePattern.java similarity index 89% rename from spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java rename to spirit-common/src/main/java/com/sum/spirit/common/pattern/TypePattern.java index 61d2b39d..9bbe58ce 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/enums/TypeEnum.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/pattern/TypePattern.java @@ -1,10 +1,11 @@ -package com.sum.spirit.common.enums; +package com.sum.spirit.common.pattern; import java.util.regex.Pattern; -public enum TypeEnum { - ; - public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); +import com.sum.spirit.common.enums.PrimitiveEnum; + +public class TypePattern { + public static final Pattern TYPE_END_PATTERN = Pattern.compile("^[\\s\\S]+\\.[A-Z]+\\w+(\\.[a-z]+\\w*)?$"); public static final Pattern TYPE_PATTERN = Pattern.compile("^[A-Z]+\\w*$"); @@ -26,7 +27,7 @@ public enum TypeEnum { } public static boolean isType(String word) { - return !CONST_VAR_PATTERN.matcher(word).matches() && TYPE_PATTERN.matcher(word).matches(); + return !LiteralPattern.isConstVariable(word) && TYPE_PATTERN.matcher(word).matches(); } public static boolean isTypeArray(String word) { @@ -58,7 +59,7 @@ public enum TypeEnum { } public static boolean isAnyType(String word) { - return !CONST_VAR_PATTERN.matcher(word).matches() && // + return !LiteralPattern.isConstVariable(word) && // (PrimitiveEnum.isPrimitiveBySimple(word) || PrimitiveEnum.isPrimitiveArrayBySimple(word) || // isType(word) || isTypeArray(word) || isGenericType(word)); } diff --git a/spirit-common/src/main/java/com/sum/spirit/common/pattern/VisitPattern.java b/spirit-common/src/main/java/com/sum/spirit/common/pattern/VisitPattern.java new file mode 100644 index 00000000..1045af8d --- /dev/null +++ b/spirit-common/src/main/java/com/sum/spirit/common/pattern/VisitPattern.java @@ -0,0 +1,28 @@ +package com.sum.spirit.common.pattern; + +import java.util.regex.Pattern; + +public class VisitPattern { + + public static final Pattern LOCAL_METHOD_PATTERN = Pattern.compile("^[a-z]+\\w*\\([\\s\\S]*\\)$"); + public static final Pattern VISIT_FIELD_PATTERN = Pattern.compile("^\\.[a-z]+\\w*$"); + public static final Pattern VISIT_METHOD_PATTERN = Pattern.compile("^\\.[a-z]+\\w*\\([\\s\\S]*\\)$"); + public static final Pattern VISIT_INDEX_PATTERN = Pattern.compile("^\\[\\d+\\]$"); + + public static boolean isLocalMethod(String word) { + return LOCAL_METHOD_PATTERN.matcher(word).matches(); + } + + public static boolean isVisitField(String word) { + return VISIT_FIELD_PATTERN.matcher(word).matches(); + } + + public static boolean isVisitMethod(String word) { + return VISIT_METHOD_PATTERN.matcher(word).matches(); + } + + public static boolean isVisitIndex(String word) { + return VISIT_INDEX_PATTERN.matcher(word).matches(); + } + +} diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index 0c68060b..4b4b739b 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -4,10 +4,11 @@ import java.util.List; import java.util.regex.Pattern; import com.sum.spirit.common.enums.KeywordEnum; -import com.sum.spirit.common.enums.LiteralEnum; import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.TokenTypeEnum; -import com.sum.spirit.common.enums.TypeEnum; +import com.sum.spirit.common.pattern.LiteralPattern; +import com.sum.spirit.common.pattern.TypePattern; +import com.sum.spirit.common.pattern.VisitPattern; import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.api.SemanticParser; import com.sum.spirit.core.element.entity.Token; @@ -16,15 +17,8 @@ public abstract class AbstractSemanticParser implements SemanticParser { public static final Pattern PATH_PATTERN = Pattern.compile("^(\\w+\\.)+\\w+$"); public static final Pattern ANNOTATION_PATTERN = Pattern.compile("^@[A-Z]+\\w+(\\([\\s\\S]+\\))?$"); - public static final Pattern SUBEXPRESS_PATTERN = Pattern.compile("^\\([\\s\\S]+\\)$"); - public static final Pattern CONST_VAR_PATTERN = Pattern.compile("^[A-Z_]{2,}$"); public static final Pattern VAR_PATTERN = Pattern.compile("^[a-z]+\\w*$"); - public static final Pattern LOCAL_METHOD_PATTERN = Pattern.compile("^[a-z]+\\w*\\([\\s\\S]*\\)$"); - public static final Pattern VISIT_FIELD_PATTERN = Pattern.compile("^\\.[a-z]+\\w*$"); - public static final Pattern VISIT_METHOD_PATTERN = Pattern.compile("^\\.[a-z]+\\w*\\([\\s\\S]*\\)$"); - public static final Pattern VISIT_INDEX_PATTERN = Pattern.compile("^\\[\\d+\\]$"); - public static final Pattern PREFIX_PATTERN = Pattern.compile("^(\\.)?\\w+$"); @Override @@ -49,7 +43,7 @@ public abstract class AbstractSemanticParser implements SemanticParser { @Override public boolean isPath(String word) { - return !LiteralEnum.isDouble(word) && PATH_PATTERN.matcher(word).matches(); + return !LiteralPattern.isDouble(word) && PATH_PATTERN.matcher(word).matches(); } @Override @@ -74,19 +68,19 @@ public abstract class AbstractSemanticParser implements SemanticParser { @Override public boolean isType(String word) { - return TypeEnum.isAnyType(word); + return TypePattern.isAnyType(word); } @Override public boolean isInit(String word) { - return TypeEnum.isAnyInit(word); + return TypePattern.isAnyInit(word); } @Override public boolean isLiteral(String word) { - return LiteralEnum.isNull(word) || LiteralEnum.isBoolean(word) || LiteralEnum.isChar(word) || // - LiteralEnum.isInt(word) || LiteralEnum.isLong(word) || LiteralEnum.isDouble(word) || // - LiteralEnum.isString(word) || LiteralEnum.isList(word) || LiteralEnum.isMap(word); + return LiteralPattern.isNull(word) || LiteralPattern.isBoolean(word) || LiteralPattern.isChar(word) || // + LiteralPattern.isInt(word) || LiteralPattern.isLong(word) || LiteralPattern.isDouble(word) || // + LiteralPattern.isString(word) || LiteralPattern.isList(word) || LiteralPattern.isMap(word); } @Override @@ -96,56 +90,53 @@ public abstract class AbstractSemanticParser implements SemanticParser { @Override public boolean isVariable(String word) { - return CONST_VAR_PATTERN.matcher(word).matches() || VAR_PATTERN.matcher(word).matches(); + return LiteralPattern.isConstVariable(word) || VAR_PATTERN.matcher(word).matches(); } @Override public boolean isAccess(String word) { - return LOCAL_METHOD_PATTERN.matcher(word).matches() || // - VISIT_FIELD_PATTERN.matcher(word).matches() || // - VISIT_METHOD_PATTERN.matcher(word).matches() || // - VISIT_INDEX_PATTERN.matcher(word).matches(); + return VisitPattern.isLocalMethod(word) || VisitPattern.isVisitField(word) || VisitPattern.isVisitMethod(word) || VisitPattern.isVisitIndex(word); } public TokenTypeEnum getInitTokenType(String word) { - if (TypeEnum.isPrimitiveArraySizeInit(word) || TypeEnum.isPrimitiveArrayLiteralInit(word)) { + if (TypePattern.isPrimitiveArraySizeInit(word) || TypePattern.isPrimitiveArrayLiteralInit(word)) { return TokenTypeEnum.ARRAY_INIT; - } else if (TypeEnum.isTypeArraySizeInit(word) || TypeEnum.isTypeArrayLiteralInit(word)) { + } else if (TypePattern.isTypeArraySizeInit(word) || TypePattern.isTypeArrayLiteralInit(word)) { return TokenTypeEnum.ARRAY_INIT; - } else if (TypeEnum.isTypeInit(word)) { + } else if (TypePattern.isTypeInit(word)) { return TokenTypeEnum.TYPE_INIT; } return null; } public TokenTypeEnum getLiteralTokenType(String word) { - if (LiteralEnum.isNull(word)) { + if (LiteralPattern.isNull(word)) { return TokenTypeEnum.NULL; - } else if (LiteralEnum.isBoolean(word)) { + } else if (LiteralPattern.isBoolean(word)) { return TokenTypeEnum.BOOLEAN; - } else if (LiteralEnum.isChar(word)) { + } else if (LiteralPattern.isChar(word)) { return TokenTypeEnum.CHAR; - } else if (LiteralEnum.isInt(word)) { + } else if (LiteralPattern.isInt(word)) { return TokenTypeEnum.INT; - } else if (LiteralEnum.isLong(word)) { + } else if (LiteralPattern.isLong(word)) { return TokenTypeEnum.LONG; - } else if (LiteralEnum.isDouble(word)) { + } else if (LiteralPattern.isDouble(word)) { return TokenTypeEnum.DOUBLE; - } else if (LiteralEnum.isString(word)) { + } else if (LiteralPattern.isString(word)) { return TokenTypeEnum.STRING; - } else if (LiteralEnum.isList(word)) { + } else if (LiteralPattern.isList(word)) { return TokenTypeEnum.LIST; - } else if (LiteralEnum.isMap(word)) { + } else if (LiteralPattern.isMap(word)) { return TokenTypeEnum.MAP; } return null; @@ -160,16 +151,16 @@ public abstract class AbstractSemanticParser implements SemanticParser { } public TokenTypeEnum getAccessTokenType(String word) { - if (LOCAL_METHOD_PATTERN.matcher(word).matches()) { + if (VisitPattern.isLocalMethod(word)) { return TokenTypeEnum.LOCAL_METHOD; - } else if (VISIT_FIELD_PATTERN.matcher(word).matches()) { + } else if (VisitPattern.isVisitField(word)) { return TokenTypeEnum.VISIT_FIELD; - } else if (VISIT_METHOD_PATTERN.matcher(word).matches()) { + } else if (VisitPattern.isVisitMethod(word)) { return TokenTypeEnum.VISIT_METHOD; - } else if (VISIT_INDEX_PATTERN.matcher(word).matches()) { + } else if (VisitPattern.isVisitIndex(word)) { return TokenTypeEnum.VISIT_INDEX; } return null; diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java index 8bd902b7..73200dac 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/AbstractLexer.java @@ -5,8 +5,8 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; -import com.sum.spirit.common.enums.LiteralEnum; -import com.sum.spirit.common.enums.TypeEnum; +import com.sum.spirit.common.pattern.LiteralPattern; +import com.sum.spirit.common.pattern.TypePattern; import com.sum.spirit.core.api.Lexer; import com.sum.spirit.core.api.LexerAction; import com.sum.spirit.core.lexer.entity.CharEvent; @@ -34,7 +34,7 @@ public abstract class AbstractLexer extends AbstractCharsHandler implements Lexe public void addToWords(List words, Region region, String text) { if (region instanceof completedRegion) { - if (text.indexOf(".") > 0 && !LiteralEnum.isDouble(text) && !TypeEnum.isTypeEnd(text)) { + if (text.indexOf(".") > 0 && !LiteralPattern.isDouble(text) && !TypePattern.isTypeEnd(text)) { List subWords = Arrays.asList(text.replaceAll("\\.", " .").split(" ")); words.addAll(subWords); return; diff --git a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java index eb821aaf..813cf941 100644 --- a/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java +++ b/spirit-core/spirit-core-lexer/src/main/java/com/sum/spirit/core/lexer/action/RegionAction.java @@ -5,8 +5,8 @@ import java.util.List; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import com.sum.spirit.common.enums.TypeEnum; import com.sum.spirit.common.exception.UnhandledException; +import com.sum.spirit.common.pattern.TypePattern; import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.api.LexerAction; import com.sum.spirit.core.lexer.entity.CharEvent; @@ -69,7 +69,7 @@ public class RegionAction implements LexerAction { } else if (ch == '[') { Region region0 = context.startIndex >= 0 ? new Region(context.startIndex, context.index) : null; - if (region0 != null && !TypeEnum.isTypePrefix(RegionUtils.subRegion(builder, region0))) { + if (region0 != null && !TypePattern.isTypePrefix(RegionUtils.subRegion(builder, region0))) { region0 = null; } Region region1 = RegionUtils.findRegion(builder, context.index, '[', ']'); -- Gitee From cc5b00bfda147b3916ab8bdc36c67d8360d8eeb3 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 17:11:59 +0800 Subject: [PATCH 103/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/common/pattern/LiteralPattern.java | 2 +- .../sum/spirit/core/api/SemanticParser.java | 8 --- .../action/AbstractSemanticParser.java | 33 ++------- .../element/action/DefaultSemanticParser.java | 69 +++++++++++-------- 4 files changed, 49 insertions(+), 63 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java b/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java index 3308830b..71616045 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java @@ -13,7 +13,7 @@ public class LiteralPattern { public static final Pattern STRING_PATTERN = Pattern.compile("^\"[\\s\\S]*\"$"); public static final Pattern LIST_PATTERN = Pattern.compile("^\\[[\\s\\S]*\\]$"); public static final Pattern MAP_PATTERN = Pattern.compile("^\\{[\\s\\S]*\\}$"); - private static final Pattern CONST_VARIABLE_PATTERN = Pattern.compile("^[A-Z_]{2,}$");// 常量也被认为是字面值的一种 + public static final Pattern CONST_VARIABLE_PATTERN = Pattern.compile("^[A-Z_]{2,}$");// 常量也被认为是字面值的一种 public static boolean isNull(String word) { return NULL_PATTERN.matcher(word).matches(); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java index fac85194..27f88006 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java @@ -26,14 +26,6 @@ public interface SemanticParser { boolean isType(String word); - boolean isInit(String word); - - boolean isLiteral(String word); - - boolean isSubexpress(String word); - boolean isVariable(String word); - boolean isAccess(String word); - } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index 4b4b739b..854d17a8 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -71,33 +71,11 @@ public abstract class AbstractSemanticParser implements SemanticParser { return TypePattern.isAnyType(word); } - @Override - public boolean isInit(String word) { - return TypePattern.isAnyInit(word); - } - - @Override - public boolean isLiteral(String word) { - return LiteralPattern.isNull(word) || LiteralPattern.isBoolean(word) || LiteralPattern.isChar(word) || // - LiteralPattern.isInt(word) || LiteralPattern.isLong(word) || LiteralPattern.isDouble(word) || // - LiteralPattern.isString(word) || LiteralPattern.isList(word) || LiteralPattern.isMap(word); - } - - @Override - public boolean isSubexpress(String word) { - return SUBEXPRESS_PATTERN.matcher(word).matches(); - } - @Override public boolean isVariable(String word) { return LiteralPattern.isConstVariable(word) || VAR_PATTERN.matcher(word).matches(); } - @Override - public boolean isAccess(String word) { - return VisitPattern.isLocalMethod(word) || VisitPattern.isVisitField(word) || VisitPattern.isVisitMethod(word) || VisitPattern.isVisitIndex(word); - } - public TokenTypeEnum getInitTokenType(String word) { if (TypePattern.isPrimitiveArraySizeInit(word) || TypePattern.isPrimitiveArrayLiteralInit(word)) { return TokenTypeEnum.ARRAY_INIT; @@ -143,11 +121,14 @@ public abstract class AbstractSemanticParser implements SemanticParser { } public TokenTypeEnum getSubexpressTokenType(String word) { - if (isType(getCastType(word))) { - return TokenTypeEnum.CAST; - } else { - return TokenTypeEnum.SUBEXPRESS; + if (SUBEXPRESS_PATTERN.matcher(word).matches()) { + if (isType(getCastType(word))) { + return TokenTypeEnum.CAST; + } else { + return TokenTypeEnum.SUBEXPRESS; + } } + return null; } public TokenTypeEnum getAccessTokenType(String word) { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java index 08e02204..dcf6c5b2 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java @@ -22,60 +22,73 @@ public class DefaultSemanticParser extends AbstractSemanticParser { @Override public Token getToken(String word, boolean insideType) { Token token = new Token(); - setTokenType(word, token, insideType); - setTokenValue(word, token); - setTokenAttributes(word, token); + + token.tokenType = getTokenType(word, insideType); + Assert.notNull(token.tokenType, "Token type cannot be null!word:[" + word + "]"); + + token.value = getTokenValue(token, word); + Assert.notNull(token.value, "Token value cannot be null!word:[" + word + "]"); + + setTokenAttributes(token, word); + return token; } - public void setTokenType(String word, Token token, boolean insideType) { + public TokenTypeEnum getTokenType(String word, boolean insideType) { if (isPath(word)) { - token.tokenType = TokenTypeEnum.PATH; + return TokenTypeEnum.PATH; } else if (isAnnotation(word)) { - token.tokenType = TokenTypeEnum.ANNOTATION; + return TokenTypeEnum.ANNOTATION; } else if (isKeyword(word)) { - token.tokenType = TokenTypeEnum.KEYWORD; + return TokenTypeEnum.KEYWORD; } else if (isOperator(word) && !insideType) {// 类型声明中,一般不包含操作符 - token.tokenType = TokenTypeEnum.OPERATOR; + return TokenTypeEnum.OPERATOR; } else if (isSeparator(word)) { - token.tokenType = TokenTypeEnum.SEPARATOR; + return TokenTypeEnum.SEPARATOR; } else if (isType(word) || (insideType && "?".equals(word))) { - token.tokenType = TokenTypeEnum.TYPE; + return TokenTypeEnum.TYPE; + } - } else if (isInit(word)) { - token.tokenType = getInitTokenType(word); + TokenTypeEnum tokenType = getInitTokenType(word); + if (tokenType != null) { + return tokenType; + } - } else if (isLiteral(word)) { - token.tokenType = getLiteralTokenType(word); + tokenType = getLiteralTokenType(word); + if (tokenType != null) { + return tokenType; + } - } else if (isSubexpress(word)) { - token.tokenType = getSubexpressTokenType(word); + tokenType = getSubexpressTokenType(word); + if (tokenType != null) { + return tokenType; + } - } else if (isVariable(word)) { - token.tokenType = TokenTypeEnum.VARIABLE; + if (isVariable(word)) { + return TokenTypeEnum.VARIABLE; + } - } else if (isAccess(word)) { - token.tokenType = getAccessTokenType(word); + tokenType = getAccessTokenType(word); + if (tokenType != null) { + return tokenType; } - Assert.notNull(token.tokenType, "Token type cannot be null!word:[" + word + "]"); + return null; } - public void setTokenValue(String word, Token token) { + public Object getTokenValue(Token token, String word) { if (token.isType()) { - token.value = getStatement(word, true); + return getStatement(word, true); } else if (token.isArrayInit() || token.isList() || token.isMap() || token.isSubexpress() || token.isInvoke()) { - token.value = getStatement(word, false);// 拆分数组是为了更好的添加new这个关键字 - - } else { - token.value = word; + return getStatement(word, false);// 拆分数组是为了更好的添加new这个关键字 } + return word; } public Object getStatement(String word, boolean insideType) { @@ -102,7 +115,7 @@ public class DefaultSemanticParser extends AbstractSemanticParser { return new Statement(tokens); } - public void setTokenAttributes(String word, Token token) { + public void setTokenAttributes(Token token, String word) { if (token.isAnnotation()) { token.setAttr(Attribute.SIMPLE_NAME, getAnnotationName(word)); -- Gitee From 563104ab70b11336435fc1f22623a15b7d2b30f7 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 17:16:56 +0800 Subject: [PATCH 104/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/common/pattern/TypePattern.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/pattern/TypePattern.java b/spirit-common/src/main/java/com/sum/spirit/common/pattern/TypePattern.java index 9bbe58ce..7480b678 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/pattern/TypePattern.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/pattern/TypePattern.java @@ -64,10 +64,4 @@ public class TypePattern { isType(word) || isTypeArray(word) || isGenericType(word)); } - public static boolean isAnyInit(String word) { - return isPrimitiveArraySizeInit(word) || isPrimitiveArrayLiteralInit(word) || // - isTypeArraySizeInit(word) || isTypeArrayLiteralInit(word) || // - isTypeInit(word); - } - } -- Gitee From cf0194391cd4f1af295c16c87336c399f9f20c84 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 17:21:10 +0800 Subject: [PATCH 105/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/core/api/SemanticParser.java | 12 ------------ .../core/element/action/AbstractSemanticParser.java | 6 ------ 2 files changed, 18 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java index 27f88006..272d287a 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java @@ -14,18 +14,6 @@ public interface SemanticParser { Token getTokenInsideType(String word); - boolean isPath(String word); - - boolean isAnnotation(String word); - - boolean isKeyword(String word); - - boolean isOperator(String word); - - boolean isSeparator(String word); - boolean isType(String word); - boolean isVariable(String word); - } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index 854d17a8..d7a6a15c 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -41,27 +41,22 @@ public abstract class AbstractSemanticParser implements SemanticParser { return getToken(word, true); } - @Override public boolean isPath(String word) { return !LiteralPattern.isDouble(word) && PATH_PATTERN.matcher(word).matches(); } - @Override public boolean isAnnotation(String word) { return ANNOTATION_PATTERN.matcher(word).matches(); } - @Override public boolean isKeyword(String word) { return KeywordEnum.isKeyword(word); } - @Override public boolean isOperator(String word) { return SymbolEnum.getOperator(word) != null; } - @Override public boolean isSeparator(String word) { return SymbolEnum.getSeparator(word) != null; } @@ -71,7 +66,6 @@ public abstract class AbstractSemanticParser implements SemanticParser { return TypePattern.isAnyType(word); } - @Override public boolean isVariable(String word) { return LiteralPattern.isConstVariable(word) || VAR_PATTERN.matcher(word).matches(); } -- Gitee From 797cfb21b6b0f7fa75a05e0f143df43d8cbf85f0 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 17:44:12 +0800 Subject: [PATCH 106/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/clazz/AbstractTypeFactory.java | 3 +- .../sum/spirit/core/api/SemanticParser.java | 9 ++-- .../core/element/DefaultElementBuilder.java | 3 +- .../action/AbstractSemanticParser.java | 22 ++------ .../element/action/DefaultSemanticParser.java | 9 ++-- .../core/element/entity/SemanticContext.java | 12 +++++ .../spirit/core/lexer/test/SemanticTest.java | 51 ++++++++++--------- 7 files changed, 53 insertions(+), 56 deletions(-) create mode 100644 spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SemanticContext.java diff --git a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractTypeFactory.java b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractTypeFactory.java index 513527db..9006e911 100644 --- a/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractTypeFactory.java +++ b/spirit-core/spirit-core-class/src/main/java/com/sum/spirit/core/clazz/AbstractTypeFactory.java @@ -11,6 +11,7 @@ import com.sum.spirit.core.api.TypeFactory; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.utils.StaticTypes; +import com.sum.spirit.core.element.entity.SemanticContext; import cn.hutool.core.lang.Assert; @@ -41,7 +42,7 @@ public abstract class AbstractTypeFactory implements TypeFactory { @Override public IType create(IClass clazz, String text) { Assert.isTrue(!text.contains("."), "Text cannot contains \".\". Please use the another create method!"); - return create(clazz, parser.getToken(text)); + return create(clazz, parser.getToken(new SemanticContext(), text)); } } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java index 272d287a..6b0b4593 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/api/SemanticParser.java @@ -2,17 +2,14 @@ package com.sum.spirit.core.api; import java.util.List; +import com.sum.spirit.core.element.entity.SemanticContext; import com.sum.spirit.core.element.entity.Token; public interface SemanticParser { - List getTokens(List words); + List getTokens(SemanticContext context, List words); - List getTokensInsideType(List words); - - Token getToken(String word); - - Token getTokenInsideType(String word); + Token getToken(SemanticContext context, String word); boolean isType(String word); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultElementBuilder.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultElementBuilder.java index 5b94675f..d7db82c1 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultElementBuilder.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultElementBuilder.java @@ -13,6 +13,7 @@ import com.sum.spirit.core.element.action.LineChecker; import com.sum.spirit.core.element.entity.Element; import com.sum.spirit.core.element.entity.Line; import com.sum.spirit.core.element.entity.Modifiers; +import com.sum.spirit.core.element.entity.SemanticContext; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.SyntaxResult; import com.sum.spirit.core.element.entity.Token; @@ -41,7 +42,7 @@ public class DefaultElementBuilder implements ElementBuilder { try { checker.check(line); // 语法校验 List words = lexer.getWords(line.text);// 1.词法分析 - List tokens = parser.getTokens(words);// 2.语义分析 + List tokens = parser.getTokens(new SemanticContext(), words);// 2.语义分析 Modifiers modifiers = new Modifiers(tokens);// 3.修饰词 Statement statement = new Statement(tokens);// 4.语句 SyntaxResult result = syntaxParser.parseSyntax(tokens, statement);// 5.分析语法 diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index d7a6a15c..7fbcb256 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -11,6 +11,7 @@ import com.sum.spirit.common.pattern.TypePattern; import com.sum.spirit.common.pattern.VisitPattern; import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.api.SemanticParser; +import com.sum.spirit.core.element.entity.SemanticContext; import com.sum.spirit.core.element.entity.Token; public abstract class AbstractSemanticParser implements SemanticParser { @@ -22,23 +23,8 @@ public abstract class AbstractSemanticParser implements SemanticParser { public static final Pattern PREFIX_PATTERN = Pattern.compile("^(\\.)?\\w+$"); @Override - public List getTokens(List words) { - return ListUtils.collectAll(words, word -> true, word -> getToken(word)); - } - - @Override - public List getTokensInsideType(List words) { - return ListUtils.collectAll(words, word -> true, word -> getTokenInsideType(word)); - } - - @Override - public Token getToken(String word) { - return getToken(word, false); - } - - @Override - public Token getTokenInsideType(String word) { - return getToken(word, true); + public List getTokens(SemanticContext context, List words) { + return ListUtils.collectAll(words, word -> true, word -> getToken(context, word)); } public boolean isPath(String word) { @@ -145,6 +131,4 @@ public abstract class AbstractSemanticParser implements SemanticParser { return word.substring(1, word.length() - 1); } - public abstract Token getToken(String word, boolean insideType); - } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java index dcf6c5b2..58dc1118 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.core.api.Lexer; +import com.sum.spirit.core.element.entity.SemanticContext; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @@ -20,10 +21,10 @@ public class DefaultSemanticParser extends AbstractSemanticParser { public Lexer lexer; @Override - public Token getToken(String word, boolean insideType) { + public Token getToken(SemanticContext context, String word) { Token token = new Token(); - token.tokenType = getTokenType(word, insideType); + token.tokenType = getTokenType(word, context.insideType); Assert.notNull(token.tokenType, "Token type cannot be null!word:[" + word + "]"); token.value = getTokenValue(token, word); @@ -104,11 +105,11 @@ public class DefaultSemanticParser extends AbstractSemanticParser { // 如果第一个单词是一个前缀的话,则添加前缀 if (PREFIX_PATTERN.matcher(first).matches()) { List subWords = words.subList(1, words.size()); - tokens = insideType ? getTokensInsideType(subWords) : getTokens(subWords); + tokens = getTokens(new SemanticContext(insideType), subWords); tokens.add(0, new Token(TokenTypeEnum.PREFIX, first)); } else { - tokens = insideType ? getTokensInsideType(words) : getTokens(words); + tokens = getTokens(new SemanticContext(insideType), words); } Assert.notNull(tokens, "Tokens cannot be null!"); diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SemanticContext.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SemanticContext.java new file mode 100644 index 00000000..44076cf3 --- /dev/null +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/entity/SemanticContext.java @@ -0,0 +1,12 @@ +package com.sum.spirit.core.element.entity; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SemanticContext { + public boolean insideType; +} diff --git a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SemanticTest.java b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SemanticTest.java index 0c2dad14..8514071a 100644 --- a/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SemanticTest.java +++ b/spirit-core/spirit-core-element/src/test/java/com/sum/spirit/core/lexer/test/SemanticTest.java @@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import com.sum.spirit.core.api.SemanticParser; +import com.sum.spirit.core.element.entity.SemanticContext; import com.sum.spirit.core.element.entity.Statement; import com.sum.spirit.core.element.entity.Token; @@ -22,7 +23,7 @@ public class SemanticTest { @DisplayName("PATH") public void test0000() { String text = "com.sum.spirit.example.Animal"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isPath()); } @@ -30,7 +31,7 @@ public class SemanticTest { @DisplayName("ANNOTATION") public void test0001() { String text = "@Animal"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isAnnotation()); } @@ -38,7 +39,7 @@ public class SemanticTest { @DisplayName("KEYWORD") public void test0002() { String text = "class"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isKeyword()); } @@ -46,7 +47,7 @@ public class SemanticTest { @DisplayName("OPERATOR") public void test0003() { String text = "="; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isOperator()); } @@ -54,7 +55,7 @@ public class SemanticTest { @DisplayName("SEPARATOR") public void test0004() { String text = "{"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isSeparator()); } @@ -62,7 +63,7 @@ public class SemanticTest { @DisplayName("TYPE") public void test0005() { String text = "Horse"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isType()); } @@ -70,7 +71,7 @@ public class SemanticTest { @DisplayName("ARRAY_INIT") public void test0006() { String text = "Horse[1]"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isArrayInit()); } @@ -78,7 +79,7 @@ public class SemanticTest { @DisplayName("TYPE_INIT") public void test0007() { String text = "Horse()"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isTypeInit()); } @@ -86,7 +87,7 @@ public class SemanticTest { @DisplayName("NULL") public void test0008() { String text = "null"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isNull()); } @@ -94,7 +95,7 @@ public class SemanticTest { @DisplayName("BOOLEAN") public void test0009() { String text = "true"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isBoolean()); } @@ -102,7 +103,7 @@ public class SemanticTest { @DisplayName("CHAR") public void test0010() { String text = "'c'"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isChar()); } @@ -110,7 +111,7 @@ public class SemanticTest { @DisplayName("INT") public void test0011() { String text = "0"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isInt()); } @@ -118,7 +119,7 @@ public class SemanticTest { @DisplayName("LONG") public void test0012() { String text = "0L"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isLong()); } @@ -126,7 +127,7 @@ public class SemanticTest { @DisplayName("DOUBLE") public void test0013() { String text = "0.0"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isDouble()); } @@ -134,7 +135,7 @@ public class SemanticTest { @DisplayName("STRING") public void test0014() { String text = "\"Jessie\""; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isString()); } @@ -142,7 +143,7 @@ public class SemanticTest { @DisplayName("LIST") public void test0015() { String text = "[\"Jessie\"]"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isList()); } @@ -150,7 +151,7 @@ public class SemanticTest { @DisplayName("MAP") public void test0016() { String text = "{\"Jessie\" : 0}"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isMap()); } @@ -158,7 +159,7 @@ public class SemanticTest { @DisplayName("SUBEXPRESS") public void test0017() { String text = "(x + y)"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isSubexpress()); } @@ -166,7 +167,7 @@ public class SemanticTest { @DisplayName("CAST") public void test0018() { String text = "(Horse)"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isCast()); } @@ -174,7 +175,7 @@ public class SemanticTest { @DisplayName("VARIABLE") public void test0019() { String text = "name"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isVariable()); } @@ -182,7 +183,7 @@ public class SemanticTest { @DisplayName("LOCAL_METHOD") public void test0020() { String text = "call()"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isLocalMethod()); } @@ -190,7 +191,7 @@ public class SemanticTest { @DisplayName("VISIT_FIELD") public void test0021() { String text = ".name"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isVisitField()); } @@ -198,7 +199,7 @@ public class SemanticTest { @DisplayName("VISIT_METHOD") public void test0022() { String text = ".call()"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isVisitMethod()); } @@ -206,7 +207,7 @@ public class SemanticTest { @DisplayName("VISIT_INDEX") public void test0023() { String text = "[0]"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); assertTrue(token.isVisitIndex()); } @@ -214,7 +215,7 @@ public class SemanticTest { @DisplayName("PREFIX") public void test0024() { String text = ".call()"; - Token token = parser.getToken(text); + Token token = parser.getToken(new SemanticContext(), text); Statement statement = token.getValue(); assertTrue(statement.get(0).isPrefix()); } -- Gitee From 951000026d433bc8ece2adb6b28a94f393850e69 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 17:52:49 +0800 Subject: [PATCH 107/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/core/element/action/DefaultSemanticParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java index 58dc1118..bd3e8819 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultSemanticParser.java @@ -100,8 +100,8 @@ public class DefaultSemanticParser extends AbstractSemanticParser { // 如果是类型,则直接用尖括号进行拆分,如果是其他,则不使用尖括号进行拆分 List words = insideType ? lexer.getSubWords(word, '<', '>') : lexer.getSubWords(word, '(', ')', '[', ']', '{', '}'); List tokens = null; - String first = words.get(0); + String first = words.get(0); // 如果第一个单词是一个前缀的话,则添加前缀 if (PREFIX_PATTERN.matcher(first).matches()) { List subWords = words.subList(1, words.size()); -- Gitee From f188725fbe08a1b88492cf8b1296979644bf2ee9 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 17:55:18 +0800 Subject: [PATCH 108/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/element/action/AbstractTreeBuilder.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractTreeBuilder.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractTreeBuilder.java index 76ee3d0b..83f2434e 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractTreeBuilder.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractTreeBuilder.java @@ -14,14 +14,10 @@ public abstract class AbstractTreeBuilder implements TreeBuilder { @Override public SyntaxTree buildTree(Statement statement) { - // 用语句构建节点树 - List nodes = buildNodes(statement); - // 标记树节点id - markTreeId(nodes); - // 标记所有的位置 - markPositionAndLength(0, statement); - // 返回抽象语法树 - return new SyntaxTree(nodes); + List nodes = buildNodes(statement);// 用语句构建节点树 + markTreeId(nodes);// 标记树节点id + markPositionAndLength(0, statement);// 标记所有的位置 + return new SyntaxTree(nodes);// 返回抽象语法树 } public void markTreeId(List nodes) { @@ -46,8 +42,7 @@ public abstract class AbstractTreeBuilder implements TreeBuilder { } public void markPositionAndLength(int position, Statement statement) { - // 获取到插入空格后 - List tokens = StmtFormat.format(statement); + List tokens = StmtFormat.format(statement);// 获取到插入空格后 for (int i = 0; i < tokens.size(); i++) { Token token = tokens.get(i); token.setAttr(Attribute.POSITION, position); -- Gitee From a7a2433676ee3c10a6bfdc151cd14d01a58f1f73 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 18:09:00 +0800 Subject: [PATCH 109/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spirit/core/compile/action/ElementExpressDeclarer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java index 218dcffb..0e6cf76f 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/action/ElementExpressDeclarer.java @@ -7,10 +7,10 @@ import org.springframework.stereotype.Component; import com.sum.spirit.common.annotation.App; import com.sum.spirit.common.constants.Attribute; import com.sum.spirit.core.api.ElementBuilder; +import com.sum.spirit.core.api.ElementVisiter; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.clazz.entity.IVariable; -import com.sum.spirit.core.compile.DefaultElementVisiter; import com.sum.spirit.core.compile.deduce.FragmentDeducer; import com.sum.spirit.core.compile.deduce.InvocationVisiter; import com.sum.spirit.core.compile.deduce.TypeDerivator; @@ -37,7 +37,7 @@ public class ElementExpressDeclarer extends AbstractScopeElementAction { @Autowired public ElementBuilder builder; @Autowired - public DefaultElementVisiter elementVisiter; + public ElementVisiter elementVisiter; @Override public void handle(ElementEvent event) { -- Gitee From b3ac8b46de9f87e8698a8df6d75cb280067745e8 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 18:16:39 +0800 Subject: [PATCH 110/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/compile/deduce/FragmentDeducer.java | 11 +++-- .../compile/linker/AdaptiveClassLinker.java | 48 +++++++++++-------- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/FragmentDeducer.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/FragmentDeducer.java index 0c8afc34..aa7a3840 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/FragmentDeducer.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/FragmentDeducer.java @@ -1,9 +1,12 @@ package com.sum.spirit.core.compile.deduce; +import java.util.List; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.sum.spirit.common.constants.Attribute; +import com.sum.spirit.common.exception.UnhandledException; import com.sum.spirit.core.api.TreeBuilder; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IType; @@ -19,18 +22,17 @@ public class FragmentDeducer { public TreeBuilder builder; public IType derive(IClass clazz, Statement statement) { - // 构建树形结构 - for (Node node : builder.buildNodes(statement)) { + List nodes = builder.buildNodes(statement); + for (Node node : nodes) { IType type = getTypeByNode(clazz, node); if (type != null) { return type; } } - throw new RuntimeException("Cannot derive the type!"); + throw new UnhandledException(); } public static IType getTypeByNode(IClass clazz, Node node) { - Token token = node.token; // 如果有类型直接返回 @@ -46,6 +48,7 @@ public class FragmentDeducer { // 先取左边的,再取右边的 if (node.prev != null) { return getTypeByNode(clazz, node.prev); + } else if (node.next != null) { return getTypeByNode(clazz, node.next); } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java index 7c35b952..4663d6a1 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AdaptiveClassLinker.java @@ -54,17 +54,20 @@ public class AdaptiveClassLinker implements ClassLinker { if (type.isPrimitive()) { return null; } + if (type.isArray()) { return StaticTypes.OBJECT; } + if (StaticTypes.OBJECT.equals(type)) { return null; } - // 如果不存在父类,则返回Object - IType superType = getLinker(type).getSuperType(type); + + IType superType = getLinker(type).getSuperType(type);// 如果不存在父类,则返回Object if (superType == null) { return StaticTypes.OBJECT; } + int modifiers = type.getModifiers(); if (modifiers == ModifierEnum.THIS.value || modifiers == ModifierEnum.SUPER.value) { superType.setModifiers(ModifierEnum.SUPER.value); @@ -72,6 +75,7 @@ public class AdaptiveClassLinker implements ClassLinker { } else if (modifiers == ModifierEnum.PUBLIC.value) { superType.setModifiers(ModifierEnum.PUBLIC.value); } + return superType; } @@ -90,29 +94,31 @@ public class AdaptiveClassLinker implements ClassLinker { public IType visitField(IType type, String fieldName) throws NoSuchFieldException { Assert.notNull(type, "Type cannot be null!"); Assert.notEmpty(fieldName, "Field name cannot be empty!"); - // xxx.class class是关键字 - if (KeywordEnum.CLASS.value.equals(fieldName)) { + + if (KeywordEnum.CLASS.value.equals(fieldName)) {// xxx.class class是关键字 return factory.create(StaticTypes.CLASS.getClassName(), derivator.toBox(type)); } - // 原始类型没有属性和方法 - if (type.isPrimitive()) { + + if (type.isPrimitive()) {// 原始类型没有属性和方法 throw new RuntimeException("The primitive type has no field!"); } - // 访问数组length直接返回int类型 - if (type.isArray() && ARRAY_LENGTH.equals(fieldName)) { + + if (type.isArray() && ARRAY_LENGTH.equals(fieldName)) {// 访问数组length直接返回int类型 return StaticTypes.INT; } - // 向上遍历推导 - IType returnType = getLinker(type).visitField(type, fieldName); + + IType returnType = getLinker(type).visitField(type, fieldName);// 向上遍历推导 if (returnType == null) { IType superType = getSuperType(type); if (superType != null) { return visitField(superType, fieldName); } } + if (returnType == null) { throw new NoSuchFieldException(String.format("No such field!className:%s, fieldName:%s", type.getClassName(), fieldName)); } + return returnType; } @@ -120,33 +126,35 @@ public class AdaptiveClassLinker implements ClassLinker { public IType visitMethod(IType type, String methodName, List parameterTypes) throws NoSuchMethodException { Assert.notNull(type, "Type cannot be null!"); Assert.notEmpty(methodName, "Method name cannot be empty!"); - // super()和this()指代父类或者本身的构造函数,返回这个类本身 - if (KeywordEnum.SUPER.value.equals(methodName) || KeywordEnum.THIS.value.equals(methodName)) { + + if (KeywordEnum.SUPER.value.equals(methodName) || KeywordEnum.THIS.value.equals(methodName)) {// super()和this()指代父类或者本身的构造函数,返回这个类本身 return type; } - // 原始类型没有属性和方法 - if (type.isPrimitive()) { + + if (type.isPrimitive()) {// 原始类型没有属性和方法 throw new RuntimeException("The primitive type has no method!"); } - // 原始类型没有属性和方法 - if (type.isArray()) { + + if (type.isArray()) {// 原始类型没有属性和方法 throw new RuntimeException("Array has no method!"); } - // 如果已经推导到Object,并且方法名是empty的话,则直接返回布尔类型 - if (StaticTypes.OBJECT.equals(type) && KeywordEnum.EMPTY.value.equals(methodName)) { + + if (StaticTypes.OBJECT.equals(type) && KeywordEnum.EMPTY.value.equals(methodName)) {// 如果已经推导到Object,并且方法名是empty的话,则直接返回布尔类型 return StaticTypes.BOOLEAN; } - // 向上遍历推导 - IType returnType = getLinker(type).visitMethod(type, methodName, parameterTypes); + + IType returnType = getLinker(type).visitMethod(type, methodName, parameterTypes);// 向上遍历推导 if (returnType == null) { IType superType = getSuperType(type); if (superType != null) { return visitMethod(superType, methodName, parameterTypes); } } + if (returnType == null) { throw new NoSuchMethodException(String.format("No such method!className:%s, methodName:%s", type.getClassName(), methodName)); } + return returnType; } -- Gitee From 9b817b0a4fdab07717a037697c78168faf054b67 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 18:25:32 +0800 Subject: [PATCH 111/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/compile/deduce/MethodMatcher.java | 31 +++++++++++++++++++ .../core/compile/linker/AppClassLinker.java | 20 +++--------- 2 files changed, 35 insertions(+), 16 deletions(-) create mode 100644 spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/MethodMatcher.java diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/MethodMatcher.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/MethodMatcher.java new file mode 100644 index 00000000..06ae1e8d --- /dev/null +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/MethodMatcher.java @@ -0,0 +1,31 @@ +package com.sum.spirit.core.compile.deduce; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.sum.spirit.core.clazz.entity.IMethod; +import com.sum.spirit.core.clazz.entity.IParameter; +import com.sum.spirit.core.clazz.entity.IType; + +@Component +public class MethodMatcher { + + @Autowired + public TypeDerivator derivator; + + public boolean matches(IType type, IMethod method, List parameterTypes) { + if (method.parameters.size() == parameterTypes.size()) { + for (int index = 0; index < method.parameters.size(); index++) { + IParameter parameter = method.parameters.get(index); + IType parameterType = derivator.populate(type, parameter.getType()); + if (!derivator.isMoreAbstract(parameterType, parameterTypes.get(index))) { + return false; + } + } + return true; + } + return false; + } +} diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java index 300f58a7..120d0886 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java @@ -13,9 +13,9 @@ import com.sum.spirit.core.api.ClassVisiter; import com.sum.spirit.core.clazz.entity.IClass; import com.sum.spirit.core.clazz.entity.IField; import com.sum.spirit.core.clazz.entity.IMethod; -import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.AppClassLoader; +import com.sum.spirit.core.compile.deduce.MethodMatcher; import com.sum.spirit.core.compile.deduce.TypeDerivator; import cn.hutool.core.lang.Assert; @@ -30,6 +30,8 @@ public class AppClassLinker implements ClassLinker { public ClassVisiter visiter; @Autowired public TypeDerivator derivator; + @Autowired + public MethodMatcher matcher; @Override @SuppressWarnings("unchecked") @@ -74,25 +76,11 @@ public class AppClassLinker implements ClassLinker { public IType visitMethod(IType type, String methodName, List parameterTypes) throws NoSuchMethodException { IClass clazz = toClass(type); List methods = clazz.getMethods(methodName); - IMethod method = ListUtils.findOne(methods, eachMethod -> matches(type, eachMethod, parameterTypes)); + IMethod method = ListUtils.findOne(methods, eachMethod -> matcher.matches(type, eachMethod, parameterTypes)); if (method != null) { return derivator.populate(type, visiter.visitMember(clazz, method)); } return null; } - public boolean matches(IType type, IMethod method, List parameterTypes) { - if (method.parameters.size() == parameterTypes.size()) { - for (int index = 0; index < method.parameters.size(); index++) { - IParameter parameter = method.parameters.get(index); - IType parameterType = derivator.populate(type, parameter.getType()); - if (!derivator.isMoreAbstract(parameterType, parameterTypes.get(index))) { - return false; - } - } - return true; - } - return false; - } - } -- Gitee From 65a61395f9ab12bd1407dca8aa1bd913a379f8e5 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 20:12:40 +0800 Subject: [PATCH 112/121] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E6=8C=89=E7=85=A7=E5=BE=97=E5=88=86=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=E8=BF=9B=E8=A1=8C=E5=8C=B9=E9=85=8D=E7=9A=84=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/common/utils/ListUtils.java | 16 ++++++---- .../core/compile/deduce/MethodMatcher.java | 25 +++++++++------- .../core/compile/deduce/TypeDerivator.java | 30 +++++++++++-------- .../core/compile/linker/AppClassLinker.java | 2 +- 4 files changed, 44 insertions(+), 29 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java index f123429c..6efa4d58 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java @@ -5,6 +5,7 @@ import java.util.Iterator; import java.util.List; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; public class ListUtils { @@ -85,13 +86,16 @@ public class ListUtils { } public static T findOneByScore(List list, Selector selector) { - Integer finalScore = null; + Integer maxScore = null; T finalItem = null; for (T item : list) { - int score = selector.accept(item); - if (finalScore == null || score > finalScore) { - finalScore = score; - finalItem = item; + Integer score = selector.accept(item); + if (score != null) { + Assert.isFalse(maxScore != null && maxScore.intValue() == score.intValue(), "The score cannot be the same!"); + if (maxScore == null || score > maxScore) { + maxScore = score; + finalItem = item; + } } } return finalItem; @@ -175,7 +179,7 @@ public class ListUtils { } public static interface Selector { - int accept(T t); + Integer accept(T t); } } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/MethodMatcher.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/MethodMatcher.java index 06ae1e8d..764de564 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/MethodMatcher.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/MethodMatcher.java @@ -15,17 +15,22 @@ public class MethodMatcher { @Autowired public TypeDerivator derivator; - public boolean matches(IType type, IMethod method, List parameterTypes) { - if (method.parameters.size() == parameterTypes.size()) { - for (int index = 0; index < method.parameters.size(); index++) { - IParameter parameter = method.parameters.get(index); - IType parameterType = derivator.populate(type, parameter.getType()); - if (!derivator.isMoreAbstract(parameterType, parameterTypes.get(index))) { - return false; - } + public Integer getMethodScore(IType type, IMethod method, List parameterTypes) { + if (method.parameters.size() != parameterTypes.size()) { + return null; + } + Integer finalScore = 0; + int index = 0; + for (IParameter parameter : method.parameters) { + IType parameterType = derivator.populate(type, parameter.getType()); + Integer scope = derivator.getAbstractScore(parameterType, parameterTypes.get(index++)); + if (scope != null) { + finalScore += scope; + } else { + finalScore = null; + break; } - return true; } - return false; + return finalScore; } } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java index 69594f78..0f47931c 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/TypeDerivator.java @@ -54,28 +54,34 @@ public class TypeDerivator { }); } - public boolean isMoreAbstract(IType abstractType, IType type) { - if (type == null) { - return false; + public Integer getAbstractScore(IType abstractType, IType type) { + if (abstractType == null || type == null) { + return null; } if (abstractType.isNull()) {// null类型不能比任何类型抽象 - return false; + return null; } if (type.isNull()) {// 任何类型都能比null抽象 - return true; + return 0; } if (type.equals(abstractType)) {// 这个方法还要判断泛型 - return true; + return 0; } - if (isMoreAbstract(abstractType, linker.getSuperType(toBox(type)))) {// 这个方法中,还要考虑到自动拆组包 - return true; + Integer score = getAbstractScore(abstractType, linker.getSuperType(toBox(type)));// 这个方法中,还要考虑到自动拆组包 + if (score != null) { + return score - 1; } - for (IType inter : linker.getInterfaceTypes(type)) {// 接口 - if (isMoreAbstract(abstractType, inter)) { - return true; + for (IType interfaceType : linker.getInterfaceTypes(type)) {// 接口 + Integer score1 = getAbstractScore(abstractType, interfaceType); + if (score1 != null) { + return score1 - 1; } } - return false; + return null; + } + + public boolean isMoreAbstract(IType abstractType, IType type) { + return getAbstractScore(abstractType, type) != null; } } diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java index 120d0886..eae4823c 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java @@ -76,7 +76,7 @@ public class AppClassLinker implements ClassLinker { public IType visitMethod(IType type, String methodName, List parameterTypes) throws NoSuchMethodException { IClass clazz = toClass(type); List methods = clazz.getMethods(methodName); - IMethod method = ListUtils.findOne(methods, eachMethod -> matcher.matches(type, eachMethod, parameterTypes)); + IMethod method = ListUtils.findOneByScore(methods, eachMethod -> matcher.getMethodScore(type, eachMethod, parameterTypes)); if (method != null) { return derivator.populate(type, visiter.visitMember(clazz, method)); } -- Gitee From 7c90d57ccd5a387b9f604ab27c7119019b37d644 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 22:06:33 +0800 Subject: [PATCH 113/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sum/spirit/common/utils/ListUtils.java | 14 +-- .../element/action/DefaultTreeBuilder.java | 10 +- .../java/deduce/NativeMethodMatcher.java | 57 ++++++++++ .../linker/AbstractNativeClassLinker.java | 62 ----------- .../output/java/linker/NativeClassLinker.java | 100 +++++++++++------- 5 files changed, 129 insertions(+), 114 deletions(-) create mode 100644 spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeMethodMatcher.java delete mode 100644 spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeClassLinker.java diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java index 6efa4d58..fd7685bf 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java @@ -66,7 +66,7 @@ public class ListUtils { return null; } - public static T findOne(List list, int fromIndex, int toIndex, Matcher matcher) { + public static T findOneByIndex(List list, int fromIndex, int toIndex, Matcher matcher) { int step = toIndex >= fromIndex ? 1 : -1; for (int index = fromIndex; index != toIndex; index += step) { T item = list.get(index); @@ -77,18 +77,14 @@ public class ListUtils { return null; } - public static T findOne(List list, Matcher matcher) { - return CollUtil.findOne(list, item -> matcher.accept(item)); - } - public static T findOne(Iterable collection, Matcher matcher) { return CollUtil.findOne(collection, item -> matcher.accept(item)); } - public static T findOneByScore(List list, Selector selector) { + public static T findOneByScore(Iterable collection, Selector selector) { Integer maxScore = null; T finalItem = null; - for (T item : list) { + for (T item : collection) { Integer score = selector.accept(item); if (score != null) { Assert.isFalse(maxScore != null && maxScore.intValue() == score.intValue(), "The score cannot be the same!"); @@ -162,6 +158,10 @@ public class ListUtils { return list0; } + public static List collectAll(List list, Matcher matcher) { + return CollUtil.filterNew(list, item -> matcher.accept(item)); + } + public static interface Matcher { boolean accept(T t); } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java index b65b32b4..b6423225 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/DefaultTreeBuilder.java @@ -88,21 +88,21 @@ public class DefaultTreeBuilder extends AbstractTreeBuilder { OperandEnum operandEnum = currentToken.attr(Attribute.OPERAND); if (operandEnum == OperandEnum.LEFT) { - Node lastNode = ListUtils.findOne(nodes, index - 1, -1, Objects::nonNull); + Node lastNode = ListUtils.findOneByIndex(nodes, index - 1, -1, Objects::nonNull); node.prev = lastNode; nodes.set(lastNode.index, null); } else if (operandEnum == OperandEnum.RIGHT) { - Node nextNode = ListUtils.findOne(nodes, index + 1, nodes.size(), Objects::nonNull); + Node nextNode = ListUtils.findOneByIndex(nodes, index + 1, nodes.size(), Objects::nonNull); node.next = nextNode; nodes.set(nextNode.index, null); } else if (operandEnum == OperandEnum.BINARY) { - Node lastNode = ListUtils.findOne(nodes, index - 1, -1, Objects::nonNull); + Node lastNode = ListUtils.findOneByIndex(nodes, index - 1, -1, Objects::nonNull); node.prev = lastNode; nodes.set(lastNode.index, null); - Node nextNode = ListUtils.findOne(nodes, index + 1, nodes.size(), Objects::nonNull); + Node nextNode = ListUtils.findOneByIndex(nodes, index + 1, nodes.size(), Objects::nonNull); node.next = nextNode; nodes.set(nextNode.index, null); @@ -116,7 +116,7 @@ public class DefaultTreeBuilder extends AbstractTreeBuilder { public void resetOperandIfMultiple(List nodes, int index, Token currentToken) { OperandEnum operandEnum = currentToken.attr(Attribute.OPERAND); if (operandEnum == OperandEnum.MULTIPLE) { - Node lastNode = ListUtils.findOne(nodes, index - 1, -1, Objects::nonNull); + Node lastNode = ListUtils.findOneByIndex(nodes, index - 1, -1, Objects::nonNull); String value = currentToken.toString(); if (SymbolEnum.SUBTRACT.value.equals(value)) {// 100 + (-10) // var = -1 if (lastNode != null) { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeMethodMatcher.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeMethodMatcher.java new file mode 100644 index 00000000..14aad299 --- /dev/null +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeMethodMatcher.java @@ -0,0 +1,57 @@ +package com.sum.spirit.output.java.deduce; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.sum.spirit.core.clazz.entity.IType; +import com.sum.spirit.output.java.utils.ReflectUtils; + +@Component +public class NativeMethodMatcher { + + @Autowired + public NativeTypeFactory factory; + @Autowired + public NativeTypeDerivator derivator; + + public boolean checkParameterCount(Method method, List parameterTypes) { + if (!ReflectUtils.isIndefinite(method) && parameterTypes.size() == method.getParameterCount()) {// 不是不定项,那么参数个数相等 + return true; + + } else if (ReflectUtils.isIndefinite(method) && parameterTypes.size() >= method.getParameterCount() - 1) {// 不定项,则参数大于等于不定项-1 + return true; + } + return false; + } + + public Integer getMethodScore(IType type, Method method, List parameterTypes) { + if (!checkParameterCount(method, parameterTypes)) { + return null; + } + Integer finalScore = 0; + int index = 0; + for (IType parameterType : parameterTypes) { + int idx = index < method.getParameterCount() - 1 ? index : method.getParameterCount() - 1;// 保证索引不会溢出 + Parameter parameter = method.getParameters()[idx];// 分为两种情况,一种是最后一个参数之前的,一种是最后一个参数 + IType nativeParameterType = factory.create(parameter.getParameterizedType());// 获取本地参数类型 + if (idx == method.getParameterCount() - 1 && ReflectUtils.isIndefinite(parameter)) {// 如果最后一个参数,而且是不定项参数,则取数组里的类型 + nativeParameterType = derivator.toTarget(nativeParameterType); + } + nativeParameterType = derivator.populateParameter(type, parameterType, nativeParameterType);// 填充类型里的泛型参数 + Integer scope = derivator.getAbstractScore(nativeParameterType, parameterType); + if (scope != null) { + finalScore += scope; + } else { + finalScore = null; + break; + } + index++; + } + return finalScore; + } + +} diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeClassLinker.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeClassLinker.java deleted file mode 100644 index 864bc2b4..00000000 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/AbstractNativeClassLinker.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.sum.spirit.output.java.linker; - -import java.lang.reflect.Type; -import java.lang.reflect.TypeVariable; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.annotation.Autowired; - -import com.sum.spirit.core.api.ClassLinker; -import com.sum.spirit.core.clazz.entity.IType; -import com.sum.spirit.output.java.ExtClassLoader; -import com.sum.spirit.output.java.deduce.NativeTypeDerivator; -import com.sum.spirit.output.java.deduce.NativeTypeFactory; - -public abstract class AbstractNativeClassLinker implements ClassLinker { - - @Autowired - public ExtClassLoader classLoader; - @Autowired - public NativeTypeFactory factory; - @Autowired - public NativeTypeDerivator derivator; - - @Override - @SuppressWarnings("unchecked") - public T toClass(IType type) { - return (T) classLoader.findClass(type.getClassName());// 可能是数组 - } - - @Override - public int getTypeVariableIndex(IType type, String genericName) { - Class clazz = toClass(type); - TypeVariable[] typeVariables = clazz.getTypeParameters(); - for (int index = 0; index < typeVariables.length; index++) { - TypeVariable typeVariable = typeVariables[index]; - if (typeVariable.toString().equals(genericName)) { - return index; - } - } - return -1; - } - - @Override - public IType getSuperType(IType type) { - Class clazz = toClass(type); - Type nativeSuperType = clazz.getGenericSuperclass(); - IType superType = nativeSuperType != null ? factory.create(nativeSuperType) : null; - return derivator.populate(type, superType); - } - - @Override - public List getInterfaceTypes(IType type) { - Class clazz = toClass(type); - List interfaceTypes = new ArrayList<>(); - for (Type interfaceType : clazz.getGenericInterfaces()) { - interfaceTypes.add(derivator.populate(type, factory.create(interfaceType))); - } - return interfaceTypes; - } - -} diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java index b0dae3d8..60598740 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java @@ -3,21 +3,78 @@ package com.sum.spirit.output.java.linker; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Parameter; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; +import com.sum.spirit.common.utils.ListUtils; +import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.clazz.entity.IType; +import com.sum.spirit.output.java.ExtClassLoader; +import com.sum.spirit.output.java.deduce.NativeMethodMatcher; +import com.sum.spirit.output.java.deduce.NativeTypeDerivator; +import com.sum.spirit.output.java.deduce.NativeTypeFactory; import com.sum.spirit.output.java.utils.ReflectUtils; import cn.hutool.core.lang.Assert; @Component @Order(-80) -public class NativeClassLinker extends AbstractNativeClassLinker { +public class NativeClassLinker implements ClassLinker { + + @Autowired + public ExtClassLoader classLoader; + @Autowired + public NativeTypeFactory factory; + @Autowired + public NativeTypeDerivator derivator; + @Autowired + public NativeMethodMatcher matcher; + + @Override + @SuppressWarnings("unchecked") + public T toClass(IType type) { + return (T) classLoader.findClass(type.getClassName());// 可能是数组 + } + + @Override + public int getTypeVariableIndex(IType type, String genericName) { + Class clazz = toClass(type); + TypeVariable[] typeVariables = clazz.getTypeParameters(); + for (int index = 0; index < typeVariables.length; index++) { + TypeVariable typeVariable = typeVariables[index]; + if (typeVariable.toString().equals(genericName)) { + return index; + } + } + return -1; + } + + @Override + public IType getSuperType(IType type) { + Class clazz = toClass(type); + Type nativeSuperType = clazz.getGenericSuperclass(); + IType superType = nativeSuperType != null ? factory.create(nativeSuperType) : null; + return derivator.populate(type, superType); + } + + @Override + public List getInterfaceTypes(IType type) { + Class clazz = toClass(type); + List interfaceTypes = new ArrayList<>(); + for (Type interfaceType : clazz.getGenericInterfaces()) { + interfaceTypes.add(derivator.populate(type, factory.create(interfaceType))); + } + return interfaceTypes; + } @Override public IType visitField(IType type, String fieldName) throws NoSuchFieldException { @@ -43,45 +100,8 @@ public class NativeClassLinker extends AbstractNativeClassLinker { public Method findMethod(IType type, String methodName, List parameterTypes) { Class clazz = toClass(type); - for (Method method : clazz.getDeclaredMethods()) { - // 方法名相同,并且参数个数相同或为不定项方法 - boolean flag = false; - if (method.getName().equals(methodName)) { - if (!ReflectUtils.isIndefinite(method) && parameterTypes.size() == method.getParameterCount()) { - flag = true; - } else if (ReflectUtils.isIndefinite(method) && parameterTypes.size() >= method.getParameterCount() - 1) { - flag = true; - } - } - // 如果不满足上一条件,直接下一个方法 - if (!flag) { - continue; - } - // 遍历传入的方法 - for (int index = 0; index < parameterTypes.size(); index++) { - IType parameterType = parameterTypes.get(index); - // 保证索引不会溢出 - int idx = index < method.getParameterCount() - 1 ? index : method.getParameterCount() - 1; - // 分为两种情况,一种是最后一个参数之前的,一种是最后一个参数 - Parameter parameter = method.getParameters()[idx]; - // 获取本地参数类型 - IType nativeParameterType = factory.create(parameter.getParameterizedType()); - // 如果最后一个参数,而且是不定项参数,则取数组里的类型 - if (idx == method.getParameterCount() - 1 && ReflectUtils.isIndefinite(parameter)) { - nativeParameterType = derivator.toTarget(nativeParameterType); - } - // 填充类型里的泛型参数 - nativeParameterType = derivator.populateParameter(type, parameterType, nativeParameterType); - if (!derivator.isMoreAbstract(nativeParameterType, parameterType)) { - flag = false; - break; - } - } - if (flag) { - return method; - } - } - return null; + List methods = ListUtils.collectAll(Arrays.asList(clazz.getDeclaredMethods()), method -> methodName.equals(method.getName())); + return ListUtils.findOneByScore(methods, eachMethod -> matcher.getMethodScore(type, eachMethod, parameterTypes)); } public Map getQualifyingTypes(IType type, Method method, List parameterTypes) { -- Gitee From f68615cf65ccc76d6d81d96d3a907bc829ebaae3 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 22:13:27 +0800 Subject: [PATCH 114/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/compile/linker/AppClassLinker.java | 1 - .../spirit/core/compile/{deduce => linker}/MethodMatcher.java | 3 ++- .../com/sum/spirit/output/java/linker/NativeClassLinker.java | 1 - .../output/java/{deduce => linker}/NativeMethodMatcher.java | 4 +++- 4 files changed, 5 insertions(+), 4 deletions(-) rename spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/{deduce => linker}/MethodMatcher.java (90%) rename spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/{deduce => linker}/NativeMethodMatcher.java (92%) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java index eae4823c..426c2373 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/AppClassLinker.java @@ -15,7 +15,6 @@ import com.sum.spirit.core.clazz.entity.IField; import com.sum.spirit.core.clazz.entity.IMethod; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.core.compile.AppClassLoader; -import com.sum.spirit.core.compile.deduce.MethodMatcher; import com.sum.spirit.core.compile.deduce.TypeDerivator; import cn.hutool.core.lang.Assert; diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/MethodMatcher.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/MethodMatcher.java similarity index 90% rename from spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/MethodMatcher.java rename to spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/MethodMatcher.java index 764de564..61eff189 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/deduce/MethodMatcher.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/MethodMatcher.java @@ -1,4 +1,4 @@ -package com.sum.spirit.core.compile.deduce; +package com.sum.spirit.core.compile.linker; import java.util.List; @@ -8,6 +8,7 @@ import org.springframework.stereotype.Component; import com.sum.spirit.core.clazz.entity.IMethod; import com.sum.spirit.core.clazz.entity.IParameter; import com.sum.spirit.core.clazz.entity.IType; +import com.sum.spirit.core.compile.deduce.TypeDerivator; @Component public class MethodMatcher { diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java index 60598740..d7b9981b 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java @@ -19,7 +19,6 @@ import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.api.ClassLinker; import com.sum.spirit.core.clazz.entity.IType; import com.sum.spirit.output.java.ExtClassLoader; -import com.sum.spirit.output.java.deduce.NativeMethodMatcher; import com.sum.spirit.output.java.deduce.NativeTypeDerivator; import com.sum.spirit.output.java.deduce.NativeTypeFactory; import com.sum.spirit.output.java.utils.ReflectUtils; diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeMethodMatcher.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeMethodMatcher.java similarity index 92% rename from spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeMethodMatcher.java rename to spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeMethodMatcher.java index 14aad299..57f4ea98 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/deduce/NativeMethodMatcher.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeMethodMatcher.java @@ -1,4 +1,4 @@ -package com.sum.spirit.output.java.deduce; +package com.sum.spirit.output.java.linker; import java.lang.reflect.Method; import java.lang.reflect.Parameter; @@ -8,6 +8,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.sum.spirit.core.clazz.entity.IType; +import com.sum.spirit.output.java.deduce.NativeTypeDerivator; +import com.sum.spirit.output.java.deduce.NativeTypeFactory; import com.sum.spirit.output.java.utils.ReflectUtils; @Component -- Gitee From 189544956e449f45b3c969e1b2d0a60633a857f4 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 22:29:48 +0800 Subject: [PATCH 115/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sum/spirit/common/utils/ListUtils.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java index fd7685bf..824e81cd 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java @@ -97,12 +97,12 @@ public class ListUtils { return finalItem; } - public static List filterStoppable(List list, Filter filter) { + public static List filterStoppable(List list, Matcher matcher) { List items = new ArrayList<>(); Iterator iterable = list.iterator(); while (iterable.hasNext()) { T item = iterable.next(); - if (filter.accept(item)) { + if (matcher.accept(item)) { items.add(item); iterable.remove(); } else { @@ -113,8 +113,8 @@ public class ListUtils { } @SuppressWarnings("unchecked") - public static List filterStoppable(List list, Filter filter, Factory factory) { - List items = filterStoppable(list, filter); + public static List filterStoppable(List list, Matcher matcher, Factory factory) { + List items = filterStoppable(list, matcher); List list0 = new ArrayList<>(); items.forEach(item -> list0.add((V) factory.accept(item))); return list0; @@ -166,10 +166,6 @@ public class ListUtils { boolean accept(T t); } - public static interface Filter { - boolean accept(T t); - } - public static interface Factory { Object accept(T t); } -- Gitee From 7da876a66e33a5deb20a2625c62a738927a40025 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 22:30:32 +0800 Subject: [PATCH 116/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/sum/spirit/common/utils/ListUtils.java | 2 +- .../java/com/sum/spirit/core/element/DefaultDocumentReader.java | 2 +- .../main/java/com/sum/spirit/core/element/frame/TokenBox.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java index 824e81cd..9684ffb2 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java @@ -48,7 +48,7 @@ public class ListUtils { return lastIndex; } - public static void remove(List list, int fromIndex, int toIndex) { + public static void removeByIndex(List list, int fromIndex, int toIndex) { for (int index = toIndex - 1; index >= fromIndex; index--) { list.remove(index); } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java index 35bdb2a8..731d993b 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/DefaultDocumentReader.java @@ -80,7 +80,7 @@ public class DefaultDocumentReader implements DocumentReader { builder.append(StrUtil.removeAny(lines.get(index), "\t").trim()); int end = LineUtils.findEndIndex(builder, 0, '{', '}'); if (end != -1) { - ListUtils.remove(lines, startIndex, index + 1); + ListUtils.removeByIndex(lines, startIndex, index + 1); lines.add(startIndex, builder.toString()); return true; } diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/TokenBox.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/TokenBox.java index c84629b6..12dd1090 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/TokenBox.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/frame/TokenBox.java @@ -38,7 +38,7 @@ public class TokenBox extends MappableList { } public void replaceTokens(int fromIndex, int toIndex, Token token) { - ListUtils.remove(this, fromIndex, toIndex); + ListUtils.removeByIndex(this, fromIndex, toIndex); add(fromIndex, token); } -- Gitee From b869caf4e12a44f0fcf628575f66662072ad6d76 Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 22:43:04 +0800 Subject: [PATCH 117/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/common/utils/ListUtils.java | 8 ++++---- .../sum/spirit/output/java/linker/NativeClassLinker.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java index 9684ffb2..92045f41 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/ListUtils.java @@ -81,6 +81,10 @@ public class ListUtils { return CollUtil.findOne(collection, item -> matcher.accept(item)); } + public static List findAll(List list, Matcher matcher) { + return CollUtil.filterNew(list, item -> matcher.accept(item)); + } + public static T findOneByScore(Iterable collection, Selector selector) { Integer maxScore = null; T finalItem = null; @@ -158,10 +162,6 @@ public class ListUtils { return list0; } - public static List collectAll(List list, Matcher matcher) { - return CollUtil.filterNew(list, item -> matcher.accept(item)); - } - public static interface Matcher { boolean accept(T t); } diff --git a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java index d7b9981b..100e4868 100644 --- a/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java +++ b/spirit-output/spirit-output-java/src/main/java/com/sum/spirit/output/java/linker/NativeClassLinker.java @@ -99,7 +99,7 @@ public class NativeClassLinker implements ClassLinker { public Method findMethod(IType type, String methodName, List parameterTypes) { Class clazz = toClass(type); - List methods = ListUtils.collectAll(Arrays.asList(clazz.getDeclaredMethods()), method -> methodName.equals(method.getName())); + List methods = ListUtils.findAll(Arrays.asList(clazz.getDeclaredMethods()), method -> methodName.equals(method.getName())); return ListUtils.findOneByScore(methods, eachMethod -> matcher.getMethodScore(type, eachMethod, parameterTypes)); } -- Gitee From ff11c18a922597a86254f3d05ac785ef5efab00a Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 22:44:05 +0800 Subject: [PATCH 118/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/common/utils/ObjectUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/utils/ObjectUtils.java b/spirit-common/src/main/java/com/sum/spirit/common/utils/ObjectUtils.java index 352d98ac..3e26459b 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/utils/ObjectUtils.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/utils/ObjectUtils.java @@ -1,13 +1,13 @@ package com.sum.spirit.common.utils; -import java.util.HashSet; import java.util.Set; +import cn.hutool.core.collection.ConcurrentHashSet; import cn.hutool.core.lang.Assert; public class ObjectUtils { - public static Set objects = new HashSet<>(); + public static Set objects = new ConcurrentHashSet<>(); public static void lock(Object obj) { Assert.isTrue(!objects.contains(obj), "Failed to acquire lock!"); -- Gitee From 5c423e16774fdc980a4e938fba64adb3067b364d Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 22:58:02 +0800 Subject: [PATCH 119/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pattern/{VisitPattern.java => AccessPattern.java} | 2 +- .../com/sum/spirit/common/pattern/LiteralPattern.java | 2 +- .../core/element/action/AbstractSemanticParser.java | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) rename spirit-common/src/main/java/com/sum/spirit/common/pattern/{VisitPattern.java => AccessPattern.java} (96%) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/pattern/VisitPattern.java b/spirit-common/src/main/java/com/sum/spirit/common/pattern/AccessPattern.java similarity index 96% rename from spirit-common/src/main/java/com/sum/spirit/common/pattern/VisitPattern.java rename to spirit-common/src/main/java/com/sum/spirit/common/pattern/AccessPattern.java index 1045af8d..c567511f 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/pattern/VisitPattern.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/pattern/AccessPattern.java @@ -2,7 +2,7 @@ package com.sum.spirit.common.pattern; import java.util.regex.Pattern; -public class VisitPattern { +public class AccessPattern { public static final Pattern LOCAL_METHOD_PATTERN = Pattern.compile("^[a-z]+\\w*\\([\\s\\S]*\\)$"); public static final Pattern VISIT_FIELD_PATTERN = Pattern.compile("^\\.[a-z]+\\w*$"); diff --git a/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java b/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java index 71616045..0d8a7b46 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java @@ -44,7 +44,7 @@ public class LiteralPattern { } public static boolean isList(String word) { - return !VisitPattern.isVisitIndex(word) && LiteralPattern.LIST_PATTERN.matcher(word).matches(); + return !AccessPattern.isVisitIndex(word) && LiteralPattern.LIST_PATTERN.matcher(word).matches(); } public static boolean isMap(String word) { diff --git a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java index 7fbcb256..255f3e78 100644 --- a/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java +++ b/spirit-core/spirit-core-element/src/main/java/com/sum/spirit/core/element/action/AbstractSemanticParser.java @@ -8,7 +8,7 @@ import com.sum.spirit.common.enums.SymbolEnum; import com.sum.spirit.common.enums.TokenTypeEnum; import com.sum.spirit.common.pattern.LiteralPattern; import com.sum.spirit.common.pattern.TypePattern; -import com.sum.spirit.common.pattern.VisitPattern; +import com.sum.spirit.common.pattern.AccessPattern; import com.sum.spirit.common.utils.ListUtils; import com.sum.spirit.core.api.SemanticParser; import com.sum.spirit.core.element.entity.SemanticContext; @@ -112,16 +112,16 @@ public abstract class AbstractSemanticParser implements SemanticParser { } public TokenTypeEnum getAccessTokenType(String word) { - if (VisitPattern.isLocalMethod(word)) { + if (AccessPattern.isLocalMethod(word)) { return TokenTypeEnum.LOCAL_METHOD; - } else if (VisitPattern.isVisitField(word)) { + } else if (AccessPattern.isVisitField(word)) { return TokenTypeEnum.VISIT_FIELD; - } else if (VisitPattern.isVisitMethod(word)) { + } else if (AccessPattern.isVisitMethod(word)) { return TokenTypeEnum.VISIT_METHOD; - } else if (VisitPattern.isVisitIndex(word)) { + } else if (AccessPattern.isVisitIndex(word)) { return TokenTypeEnum.VISIT_INDEX; } return null; -- Gitee From 98322c4cada31a85e06e9192ea2dc1f9b2a6931e Mon Sep 17 00:00:00 2001 From: chenT Date: Wed, 5 May 2021 22:58:35 +0800 Subject: [PATCH 120/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sum/spirit/common/pattern/LiteralPattern.java | 1 + 1 file changed, 1 insertion(+) diff --git a/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java b/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java index 0d8a7b46..f09c8d33 100644 --- a/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java +++ b/spirit-common/src/main/java/com/sum/spirit/common/pattern/LiteralPattern.java @@ -13,6 +13,7 @@ public class LiteralPattern { public static final Pattern STRING_PATTERN = Pattern.compile("^\"[\\s\\S]*\"$"); public static final Pattern LIST_PATTERN = Pattern.compile("^\\[[\\s\\S]*\\]$"); public static final Pattern MAP_PATTERN = Pattern.compile("^\\{[\\s\\S]*\\}$"); + public static final Pattern CONST_VARIABLE_PATTERN = Pattern.compile("^[A-Z_]{2,}$");// 常量也被认为是字面值的一种 public static boolean isNull(String word) { -- Gitee From 2a348f91a6b325f740fb6ec67c11923eff9fcd83 Mon Sep 17 00:00:00 2001 From: "tao.chen1" Date: Thu, 6 May 2021 09:52:32 +0800 Subject: [PATCH 121/121] =?UTF-8?q?=E7=AE=80=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sum/spirit/core/compile/linker/MethodMatcher.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/MethodMatcher.java b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/MethodMatcher.java index 61eff189..740b377b 100644 --- a/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/MethodMatcher.java +++ b/spirit-core/spirit-core-compile/src/main/java/com/sum/spirit/core/compile/linker/MethodMatcher.java @@ -22,9 +22,10 @@ public class MethodMatcher { } Integer finalScore = 0; int index = 0; - for (IParameter parameter : method.parameters) { - IType parameterType = derivator.populate(type, parameter.getType()); - Integer scope = derivator.getAbstractScore(parameterType, parameterTypes.get(index++)); + for (IType parameterType : parameterTypes) { + IParameter parameter = method.parameters.get(index++); + IType methodParameterType = derivator.populate(type, parameter.getType()); + Integer scope = derivator.getAbstractScore(methodParameterType, parameterType); if (scope != null) { finalScore += scope; } else { -- Gitee