未验证 提交 29b999ae 编写于 作者: P Phodal Huang

feat: add suggest detail

上级 a4f7a19a
......@@ -16,6 +16,7 @@ Todo:
- [ ] Suggest API for Design Patterns
- [x] factory pattern
- [ ] strategy
- [ ] builder
## Usage
......
package com.ilscipio.scipio.accounting.external.datev;
import java.lang.reflect.Constructor;
import java.util.Iterator;
import java.util.Map;
import org.ofbiz.base.util.Debug;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericValue;
import com.ilscipio.scipio.accounting.external.BaseOperationResults;
import com.ilscipio.scipio.accounting.external.BaseOperationStats;
import com.ilscipio.scipio.accounting.external.BaseOperationStats.NotificationLevel;
import com.ilscipio.scipio.accounting.external.BaseOperationStats.NotificationScope;
import com.ilscipio.scipio.accounting.external.BaseOperationStats.Stat;
import com.ilscipio.scipio.accounting.external.datev.category.AbstractDatevDataCategory;
public class DatevHelper {
private static final Debug.OfbizLogger module = Debug.getOfbizLogger(java.lang.invoke.MethodHandles.lookup().lookupClass());
private final String orgPartyId;
private final BaseOperationStats stats;
private final BaseOperationResults results;
private final AbstractDatevDataCategory dataCategoryImpl;
private final GenericValue dataCategory;
private final GenericValue dataCategorySettings;
public DatevHelper(Delegator delegator, String orgPartyId, GenericValue dataCategory) throws DatevException {
this.orgPartyId = orgPartyId;
try {
this.dataCategory = dataCategory;
this.dataCategorySettings = dataCategory.getRelatedOne("DatevGeneralSetting", true);
@SuppressWarnings("unchecked")
Class<? extends AbstractDatevDataCategory> dataCategoryClass = (Class<? extends AbstractDatevDataCategory>) Class.forName(dataCategory.getString("dataCategoryClass"));
Constructor<? extends AbstractDatevDataCategory> datevDataCategoryConstructor = dataCategoryClass.getConstructor(Delegator.class, DatevHelper.class);
this.dataCategoryImpl = datevDataCategoryConstructor.newInstance(delegator, this);
if (dataCategoryImpl.getOperationStatsClass() != null)
this.stats = dataCategoryImpl.getOperationStatsClass().newInstance();
else
this.stats = BaseOperationStats.class.newInstance();
if (dataCategoryImpl.getOperationResultsClass() != null)
this.results = dataCategoryImpl.getOperationResultsClass().newInstance();
else
this.results = BaseOperationResults.class.newInstance();
if (Debug.isOn(Debug.VERBOSE)) {
Debug.logInfo("Datev helper succesfully initialized.", module);
}
} catch (Exception e) {
throw new DatevException("Internal error. Cannot initialize DATEV helper.");
}
}
public boolean hasFatalNotification() {
if (stats != null) {
for (Stat stat : stats.getStats()) {
if (stat.getLevel().equals(NotificationLevel.FATAL))
return true;
}
}
return false;
}
public void processRecord(int index, Map<String, String> recordMap) throws DatevException {
dataCategoryImpl.processRecord(index, recordMap);
}
public String[] getFieldNames() throws DatevException {
return dataCategoryImpl.getDatevFieldNames();
}
public boolean validateField(Object o, String value) throws DatevException {
if (o instanceof String)
return dataCategoryImpl.validateField(String.valueOf(o), value);
else if (o instanceof Integer)
return dataCategoryImpl.validateField((Integer) o, value);
return false;
}
public String getOrgPartyId() {
return orgPartyId;
}
public boolean isMetaHeader(Iterator<String> metaHeader) throws DatevException {
return dataCategoryImpl.isMetaHeader(metaHeader);
}
public BaseOperationResults getResults() {
return results;
}
public BaseOperationStats getStats() {
return stats;
}
public GenericValue getDataCategory() {
return dataCategory;
}
public GenericValue getDataCategorySettings() {
return dataCategorySettings;
}
public void addRecordStat(String message, NotificationLevel level, int position, Map<String, String> value, boolean valid) {
addStat(stats.new RecordStat(message, level, position, value, valid));
}
public void addStat(String message, NotificationScope scope, NotificationLevel level) {
addStat(stats.new Stat(message, scope, level));
}
private void addStat(Stat stat) {
stats.addStat(stat);
}
}
package builder;
public class BeeBuilder extends Insect {
public BeeBuilder(int size) {
super(size);
System.out.println("Constructor: BeeBuilder size");
}
public BeeBuilder(int size, int height) {
super(size, height);
System.out.println("Constructor: BeeBuilder size, height");
}
public BeeBuilder(int size, int height, String color) {
super(size, height);
System.out.println("Constructor: BeeBuilder size, height, color");
}
public BeeBuilder(int size, int height, String color, int x, int y, int z) {
super(size, height);
System.out.println("Constructor: BeeBuilder size, height, color");
}
}
\ No newline at end of file
......@@ -22,18 +22,16 @@ var todoCmd = &cobra.Command{
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
path := cmd.Flag("path").Value.String()
if path != "" {
app := todo.NewTodoApp()
todos := app.AnalysisPath(path)
app := todo.NewTodoApp()
todos := app.AnalysisPath(path)
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Date", "Author", "Messages", "FileName", "Line"})
for _, todo := range todos {
table.Append([]string{todo.Date, todo.Author, strings.Join(todo.Message, "\n"), todo.FileName, todo.Line})
}
table.Render()
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Date", "Author", "Messages", "FileName", "Line"})
for _, todo := range todos {
table.Append([]string{todo.Date, todo.Author, strings.Join(todo.Message, "\n"), todo.FileName, todo.Line})
}
table.Render()
},
}
......
......@@ -207,10 +207,17 @@ func (s *JavaCallListener) EnterConstructorDeclaration(ctx *parser.ConstructorDe
StopLine: ctx.GetStop().GetLine(),
StopLinePosition: ctx.GetStop().GetColumn(),
Override: isOverrideMethod,
Parameters: nil,
Annotations: currentMethod.Annotations,
IsConstructor: true,
}
parameters := ctx.FormalParameters()
if buildMethodParameters(parameters, method) {
return
}
updateMethod(method)
}
......@@ -230,14 +237,23 @@ func (s *JavaCallListener) EnterMethodDeclaration(ctx *parser.MethodDeclarationC
method := &models.JMethod{name, typeType, startLine, startLinePosition, stopLine, stopLinePosition, nil, nil, false, nil, false}
if ctx.FormalParameters() != nil {
if ctx.FormalParameters().GetChild(0) == nil || ctx.FormalParameters().GetText() == "()" || ctx.FormalParameters().GetChild(1) == nil {
parameters := ctx.FormalParameters()
if buildMethodParameters(parameters, method) {
return
}
updateMethod(method)
}
func buildMethodParameters(parameters parser.IFormalParametersContext, method *models.JMethod) bool {
if parameters != nil {
if parameters.GetChild(0) == nil || parameters.GetText() == "()" || parameters.GetChild(1) == nil {
updateMethod(method)
return
return true
}
var methodParams []models.JParameter = nil
parameterList := ctx.FormalParameters().GetChild(1).(*parser.FormalParameterListContext)
parameterList := parameters.GetChild(1).(*parser.FormalParameterListContext)
formalParameter := parameterList.AllFormalParameter()
for _, param := range formalParameter {
paramContext := param.(*parser.FormalParameterContext)
......@@ -250,8 +266,7 @@ func (s *JavaCallListener) EnterMethodDeclaration(ctx *parser.MethodDeclarationC
method.Parameters = methodParams
}
updateMethod(method)
return false
}
func updateMethod(method *models.JMethod) {
......@@ -265,7 +280,7 @@ func (s *JavaCallListener) ExitMethodDeclaration(ctx *parser.MethodDeclarationCo
}
func exitMethod() {
if len(methodQueue) < 1 {
if methodQueue == nil || len(methodQueue) < 1 {
currentMethod = models.NewJMethod()
return
}
......@@ -280,18 +295,20 @@ func exitMethod() {
// TODO: add inner creator examples
func (s *JavaCallListener) EnterInnerCreator(ctx *parser.InnerCreatorContext) {
currentClz = ctx.IDENTIFIER().GetText()
classQueue = append(classQueue, currentClz)
if ctx.IDENTIFIER() != nil {
currentClz = ctx.IDENTIFIER().GetText()
classQueue = append(classQueue, currentClz)
}
}
// TODO: add inner creator examples
func (s *JavaCallListener) ExitInnerCreator(ctx *parser.InnerCreatorContext) {
if len(classQueue) <= 1 {
if classQueue == nil || len(classQueue) <= 1 {
return
}
classQueue = classQueue[0 : len(classQueue)-1]
currentClz = classQueue[len(classQueue)]
currentClz = classQueue[len(classQueue) - 1]
}
func getMethodMapName(method models.JMethod) string {
......
......@@ -8,6 +8,8 @@ type Suggest struct {
Class string
Pattern string
Reason string
Size int
Line int
}
func NewSuggest(clz models.JClassNode, pattern, reason string) Suggest {
......
......@@ -13,11 +13,14 @@ func NewSuggestApp() SuggestApp {
func (a SuggestApp) AnalysisPath(deps []models.JClassNode) []Suggest {
var suggests []Suggest
// TODO: DSL => class constructor.len > 3
for _, clz := range deps {
if clz.Type == "Class" {
suggests = factorySuggest(clz, suggests)
// TODO: DSL => class constructor.len > 3
if len(clz.Methods) > 0 {
suggests = factorySuggest(clz, suggests)
}
}
// TODO: long parameters in constructor builder
}
return suggests
......@@ -25,14 +28,37 @@ func (a SuggestApp) AnalysisPath(deps []models.JClassNode) []Suggest {
func factorySuggest(clz models.JClassNode, suggests []Suggest) []Suggest {
var constructorCount = 0
var longestParaConstructorMethod = clz.Methods[0]
for _, method := range clz.Methods {
if method.IsConstructor {
constructorCount++
if len(method.Parameters) >= len(longestParaConstructorMethod.Parameters) {
longestParaConstructorMethod = method
}
declLineNum := method.StopLine - method.StartLine
// 参数过多,且在构造函数里调用过多
if declLineNum > len(method.Parameters)-3 && len(method.MethodCalls) > 3 {
suggest := NewSuggest(clz, "factory", "complex constructor")
suggest.Line = method.StartLine
suggests = append(suggests, suggest)
}
}
}
// TODO 合并 suggest
if constructorCount >= 3 {
suggests = append(suggests, NewSuggest(clz, "factory", "to many constructor"))
suggest := NewSuggest(clz, "factory", "too many constructor")
suggest.Size = constructorCount
suggests = append(suggests, suggest)
}
if len(longestParaConstructorMethod.Parameters) >= 5 {
suggest := NewSuggest(clz, "builder", "too many parameters")
suggest.Size = len(longestParaConstructorMethod.Parameters)
suggests = append(suggests, suggest)
}
return suggests
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册