langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java
changeset 38513 0ae85633d035
parent 37745 4b6b59f8e327
child 38520 17e72b872ffd
equal deleted inserted replaced
38512:c71e1cdd6674 38513:0ae85633d035
    45 class Feedback {
    45 class Feedback {
    46 
    46 
    47     // Patern for substituted fields within a customized format string
    47     // Patern for substituted fields within a customized format string
    48     private static final Pattern FIELD_PATTERN = Pattern.compile("\\{(.*?)\\}");
    48     private static final Pattern FIELD_PATTERN = Pattern.compile("\\{(.*?)\\}");
    49 
    49 
       
    50     // Internal field name for truncation length
       
    51     private static final String TRUNCATION_FIELD = "<truncation>";
       
    52 
    50     // Current mode
    53     // Current mode
    51     private Mode mode = new Mode("", false); // initial value placeholder during start-up
    54     private Mode mode = new Mode("", false); // initial value placeholder during start-up
    52 
    55 
    53     // Mapping of mode names to mode modes
    56     // Mapping of mode names to mode modes
    54     private final Map<String, Mode> modeMap = new HashMap<>();
    57     private final Map<String, Mode> modeMap = new HashMap<>();
    99         return new Setter(messageHandler, at).setFeedback();
   102         return new Setter(messageHandler, at).setFeedback();
   100     }
   103     }
   101 
   104 
   102     public boolean setFormat(MessageHandler messageHandler, ArgTokenizer at) {
   105     public boolean setFormat(MessageHandler messageHandler, ArgTokenizer at) {
   103         return new Setter(messageHandler, at).setFormat();
   106         return new Setter(messageHandler, at).setFormat();
       
   107     }
       
   108 
       
   109     public boolean setTruncation(MessageHandler messageHandler, ArgTokenizer at) {
       
   110         return new Setter(messageHandler, at).setTruncation();
   104     }
   111     }
   105 
   112 
   106     public boolean setNewMode(MessageHandler messageHandler, ArgTokenizer at) {
   113     public boolean setNewMode(MessageHandler messageHandler, ArgTokenizer at) {
   107         return new Setter(messageHandler, at).setNewMode();
   114         return new Setter(messageHandler, at).setNewMode();
   108     }
   115     }
   249             }
   256             }
   250             m.appendTail(sb);
   257             m.appendTail(sb);
   251             return sb.toString();
   258             return sb.toString();
   252         }
   259         }
   253 
   260 
       
   261         // Compute the display output given full context and values
   254         String format(FormatCase fc, FormatAction fa, FormatWhen fw,
   262         String format(FormatCase fc, FormatAction fa, FormatWhen fw,
   255                     FormatResolve fr, FormatUnresolved fu, FormatErrors fe,
   263                     FormatResolve fr, FormatUnresolved fu, FormatErrors fe,
   256                     String name, String type, String value, String unresolved, List<String> errorLines) {
   264                     String name, String type, String value, String unresolved, List<String> errorLines) {
       
   265             // Convert the context into a bit representation used as selectors for store field formats
   257             long bits = bits(fc, fa, fw, fr, fu, fe);
   266             long bits = bits(fc, fa, fw, fr, fu, fe);
   258             String fname = name==null? "" : name;
   267             String fname = name==null? "" : name;
   259             String ftype = type==null? "" : type;
   268             String ftype = type==null? "" : type;
   260             String fvalue = value==null? "" : value;
   269             // Compute the representation of value
       
   270             String fvalue;
       
   271             if (value==null) {
       
   272                 fvalue = "";
       
   273             } else {
       
   274                 // Retrieve the truncation length
       
   275                 String truncField = format(TRUNCATION_FIELD, bits);
       
   276                 if (truncField.isEmpty()) {
       
   277                     // No truncation set, use whole value
       
   278                     fvalue = value;
       
   279                 } else {
       
   280                     // Convert truncation length to int
       
   281                     // this is safe since it has been tested before it is set
       
   282                     int trunc = Integer.parseUnsignedInt(truncField);
       
   283                     if (value.length() > trunc) {
       
   284                         if (trunc <= 5) {
       
   285                             // Very short truncations have no room for "..."
       
   286                             fvalue = value.substring(0, trunc);
       
   287                         } else {
       
   288                             // Normal truncation, make total length equal truncation length
       
   289                             fvalue = value.substring(0, trunc - 4) + " ...";
       
   290                         }
       
   291                     } else {
       
   292                         // Within truncation length, use whole value
       
   293                         fvalue = value;
       
   294                     }
       
   295                 }
       
   296             }
   261             String funresolved = unresolved==null? "" : unresolved;
   297             String funresolved = unresolved==null? "" : unresolved;
   262             String errors = errorLines.stream()
   298             String errors = errorLines.stream()
   263                     .map(el -> String.format(
   299                     .map(el -> String.format(
   264                             format("errorline", bits),
   300                             format("errorline", bits),
   265                             fname, ftype, fvalue, funresolved, "*cannot-use-errors-here*", el))
   301                             fname, ftype, fvalue, funresolved, "*cannot-use-errors-here*", el))
   617             String field = at.next();
   653             String field = at.next();
   618             if (field == null || at.isQuoted()) {
   654             if (field == null || at.isQuoted()) {
   619                 errorat("jshell.err.feedback.expected.field");
   655                 errorat("jshell.err.feedback.expected.field");
   620                 valid = false;
   656                 valid = false;
   621             }
   657             }
   622             String format = valid? nextFormat() : null;
   658             String format = valid ? nextFormat() : null;
       
   659             return installFormat(m, field, format, "/help /set format");
       
   660         }
       
   661 
       
   662         // For /set truncation <mode> <length> <selector>...
       
   663         boolean setTruncation() {
       
   664             Mode m = nextMode();
       
   665             String length = at.next();
       
   666             if (length == null) {
       
   667                 errorat("jshell.err.truncation.expected.length");
       
   668                 valid = false;
       
   669             } else {
       
   670                 try {
       
   671                     // Assure that integer format is correct
       
   672                     Integer.parseUnsignedInt(length);
       
   673                 } catch (NumberFormatException ex) {
       
   674                     errorat("jshell.err.truncation.length.not.integer", length);
       
   675                     valid = false;
       
   676                 }
       
   677             }
       
   678             // install length into an internal format field
       
   679             return installFormat(m, TRUNCATION_FIELD, length, "/help /set truncation");
       
   680         }
       
   681 
       
   682         // install the format of a field under parsed selectors
       
   683         boolean installFormat(Mode m, String field, String format, String help) {
   623             String slRaw;
   684             String slRaw;
   624             List<SelectorList> slList = new ArrayList<>();
   685             List<SelectorList> slList = new ArrayList<>();
   625             while (valid && (slRaw = at.next()) != null) {
   686             while (valid && (slRaw = at.next()) != null) {
   626                 SelectorList sl = new SelectorList();
   687                 SelectorList sl = new SelectorList();
   627                 sl.parseSelectorList(slRaw);
   688                 sl.parseSelectorList(slRaw);
   628                 slList.add(sl);
   689                 slList.add(sl);
   629             }
   690             }
   630             if (valid) {
   691             if (valid) {
   631                 if (slList.isEmpty()) {
   692                 if (slList.isEmpty()) {
       
   693                     // No selectors specified, then always the format
   632                     m.set(field, ALWAYS, format);
   694                     m.set(field, ALWAYS, format);
   633                 } else {
   695                 } else {
       
   696                     // Set the format of the field for specified selector
   634                     slList.stream()
   697                     slList.stream()
   635                             .forEach(sl -> m.set(field,
   698                             .forEach(sl -> m.set(field,
   636                                 sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(),
   699                                 sl.cases.getSet(), sl.actions.getSet(), sl.whens.getSet(),
   637                                 sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(),
   700                                 sl.resolves.getSet(), sl.unresolvedCounts.getSet(), sl.errorCounts.getSet(),
   638                                 format));
   701                                 format));
   639                 }
   702                 }
   640             } else {
   703             } else {
   641                 fluffmsg("jshell.msg.see", "/help /set format");
   704                 fluffmsg("jshell.msg.see", help);
   642             }
   705             }
   643             return valid;
   706             return valid;
   644         }
   707         }
   645 
   708 
   646         Mode nextMode() {
   709         Mode nextMode() {