langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java
changeset 40498 f54048be4a57
parent 40318 3f7eb1205cee
child 40517 611ca58fca75
equal deleted inserted replaced
40320:2e83d21d78cd 40498:f54048be4a57
   169     @Override
   169     @Override
   170     public CompletionInfo analyzeCompletion(String srcInput) {
   170     public CompletionInfo analyzeCompletion(String srcInput) {
   171         MaskCommentsAndModifiers mcm = new MaskCommentsAndModifiers(srcInput, false);
   171         MaskCommentsAndModifiers mcm = new MaskCommentsAndModifiers(srcInput, false);
   172         if (mcm.endsWithOpenComment()) {
   172         if (mcm.endsWithOpenComment()) {
   173             proc.debug(DBG_COMPA, "Incomplete (open comment): %s\n", srcInput);
   173             proc.debug(DBG_COMPA, "Incomplete (open comment): %s\n", srcInput);
   174             return new CompletionInfo(DEFINITELY_INCOMPLETE, srcInput.length(), null, srcInput + '\n');
   174             return new CompletionInfoImpl(DEFINITELY_INCOMPLETE, null, srcInput + '\n');
   175         }
   175         }
   176         String cleared = mcm.cleared();
   176         String cleared = mcm.cleared();
   177         String trimmedInput = Util.trimEnd(cleared);
   177         String trimmedInput = Util.trimEnd(cleared);
   178         if (trimmedInput.isEmpty()) {
   178         if (trimmedInput.isEmpty()) {
   179             // Just comment or empty
   179             // Just comment or empty
   180             return new CompletionInfo(Completeness.EMPTY, srcInput.length(), srcInput, "");
   180             return new CompletionInfoImpl(Completeness.EMPTY, srcInput, "");
   181         }
   181         }
   182         CaInfo info = ca.scan(trimmedInput);
   182         CaInfo info = ca.scan(trimmedInput);
   183         Completeness status = info.status;
   183         Completeness status = info.status;
   184         int unitEndPos = info.unitEndPos;
   184         int unitEndPos = info.unitEndPos;
   185         if (unitEndPos > srcInput.length()) {
   185         if (unitEndPos > srcInput.length()) {
   193                     // The unit is the whole non-coment/white input plus semicolon
   193                     // The unit is the whole non-coment/white input plus semicolon
   194                     String compileSource = src
   194                     String compileSource = src
   195                             + mcm.mask().substring(nonCommentNonWhiteLength);
   195                             + mcm.mask().substring(nonCommentNonWhiteLength);
   196                     proc.debug(DBG_COMPA, "Complete: %s\n", compileSource);
   196                     proc.debug(DBG_COMPA, "Complete: %s\n", compileSource);
   197                     proc.debug(DBG_COMPA, "   nothing remains.\n");
   197                     proc.debug(DBG_COMPA, "   nothing remains.\n");
   198                     return new CompletionInfo(status, unitEndPos, compileSource, "");
   198                     return new CompletionInfoImpl(status, compileSource, "");
   199                 } else {
   199                 } else {
   200                     String remain = srcInput.substring(unitEndPos);
   200                     String remain = srcInput.substring(unitEndPos);
   201                     proc.debug(DBG_COMPA, "Complete: %s\n", src);
   201                     proc.debug(DBG_COMPA, "Complete: %s\n", src);
   202                     proc.debug(DBG_COMPA, "          remaining: %s\n", remain);
   202                     proc.debug(DBG_COMPA, "          remaining: %s\n", remain);
   203                     return new CompletionInfo(status, unitEndPos, src, remain);
   203                     return new CompletionInfoImpl(status, src, remain);
   204                 }
   204                 }
   205             case COMPLETE_WITH_SEMI:
   205             case COMPLETE_WITH_SEMI:
   206                 // The unit is the whole non-coment/white input plus semicolon
   206                 // The unit is the whole non-coment/white input plus semicolon
   207                 String compileSource = src
   207                 String compileSource = src
   208                         + ";"
   208                         + ";"
   209                         + mcm.mask().substring(nonCommentNonWhiteLength);
   209                         + mcm.mask().substring(nonCommentNonWhiteLength);
   210                 proc.debug(DBG_COMPA, "Complete with semi: %s\n", compileSource);
   210                 proc.debug(DBG_COMPA, "Complete with semi: %s\n", compileSource);
   211                 proc.debug(DBG_COMPA, "   nothing remains.\n");
   211                 proc.debug(DBG_COMPA, "   nothing remains.\n");
   212                 return new CompletionInfo(status, unitEndPos, compileSource, "");
   212                 return new CompletionInfoImpl(status, compileSource, "");
   213             case DEFINITELY_INCOMPLETE:
   213             case DEFINITELY_INCOMPLETE:
   214                 proc.debug(DBG_COMPA, "Incomplete: %s\n", srcInput);
   214                 proc.debug(DBG_COMPA, "Incomplete: %s\n", srcInput);
   215                 return new CompletionInfo(status, unitEndPos, null, srcInput + '\n');
   215                 return new CompletionInfoImpl(status, null, srcInput + '\n');
   216             case CONSIDERED_INCOMPLETE:
   216             case CONSIDERED_INCOMPLETE:
   217                 proc.debug(DBG_COMPA, "Considered incomplete: %s\n", srcInput);
   217                 proc.debug(DBG_COMPA, "Considered incomplete: %s\n", srcInput);
   218                 return new CompletionInfo(status, unitEndPos, null, srcInput + '\n');
   218                 return new CompletionInfoImpl(status, null, srcInput + '\n');
   219             case EMPTY:
   219             case EMPTY:
   220                 proc.debug(DBG_COMPA, "Detected empty: %s\n", srcInput);
   220                 proc.debug(DBG_COMPA, "Detected empty: %s\n", srcInput);
   221                 return new CompletionInfo(status, unitEndPos, srcInput, "");
   221                 return new CompletionInfoImpl(status, srcInput, "");
   222             case UNKNOWN:
   222             case UNKNOWN:
   223                 proc.debug(DBG_COMPA, "Detected error: %s\n", srcInput);
   223                 proc.debug(DBG_COMPA, "Detected error: %s\n", srcInput);
   224                 return new CompletionInfo(status, unitEndPos, srcInput, "");
   224                 return new CompletionInfoImpl(status, srcInput, "");
   225         }
   225         }
   226         throw new InternalError();
   226         throw new InternalError();
   227     }
   227     }
   228 
   228 
   229     private Tree.Kind guessKind(String code) {
   229     private Tree.Kind guessKind(String code) {
   663             }
   663             }
   664             String simpleName = simpleName(c);
   664             String simpleName = simpleName(c);
   665             if (c.getKind() == ElementKind.CONSTRUCTOR || c.getKind() == ElementKind.METHOD) {
   665             if (c.getKind() == ElementKind.CONSTRUCTOR || c.getKind() == ElementKind.METHOD) {
   666                 simpleName += paren.apply(hasParams.contains(simpleName));
   666                 simpleName += paren.apply(hasParams.contains(simpleName));
   667             }
   667             }
   668             result.add(new Suggestion(simpleName, smart.test(c)));
   668             result.add(new SuggestionImpl(simpleName, smart.test(c)));
   669         }
   669         }
   670     }
   670     }
   671 
   671 
   672     private String simpleName(Element el) {
   672     private String simpleName(Element el) {
   673         return el.getKind() == ElementKind.CONSTRUCTOR ? el.getEnclosingElement().getSimpleName().toString()
   673         return el.getKind() == ElementKind.CONSTRUCTOR ? el.getEnclosingElement().getSimpleName().toString()
  1698             synchronized (currentIndexes) {
  1698             synchronized (currentIndexes) {
  1699                 upToDate = classpathVersion == indexVersion;
  1699                 upToDate = classpathVersion == indexVersion;
  1700             }
  1700             }
  1701         }
  1701         }
  1702     }
  1702     }
       
  1703 
       
  1704     /**
       
  1705      * A candidate for continuation of the given user's input.
       
  1706      */
       
  1707     private static class SuggestionImpl implements Suggestion {
       
  1708 
       
  1709         private final String continuation;
       
  1710         private final boolean matchesType;
       
  1711 
       
  1712         /**
       
  1713          * Create a {@code Suggestion} instance.
       
  1714          *
       
  1715          * @param continuation a candidate continuation of the user's input
       
  1716          * @param matchesType does the candidate match the target type
       
  1717          */
       
  1718         public SuggestionImpl(String continuation, boolean matchesType) {
       
  1719             this.continuation = continuation;
       
  1720             this.matchesType = matchesType;
       
  1721         }
       
  1722 
       
  1723         /**
       
  1724          * The candidate continuation of the given user's input.
       
  1725          *
       
  1726          * @return the continuation string
       
  1727          */
       
  1728         @Override
       
  1729         public String continuation() {
       
  1730             return continuation;
       
  1731         }
       
  1732 
       
  1733         /**
       
  1734          * Indicates whether input continuation matches the target type and is thus
       
  1735          * more likely to be the desired continuation. A matching continuation is
       
  1736          * preferred.
       
  1737          *
       
  1738          * @return {@code true} if this suggested continuation matches the
       
  1739          * target type; otherwise {@code false}
       
  1740          */
       
  1741         @Override
       
  1742         public boolean matchesType() {
       
  1743             return matchesType;
       
  1744         }
       
  1745     }
       
  1746 
       
  1747     /**
       
  1748      * The result of {@code analyzeCompletion(String input)}.
       
  1749      * Describes the completeness and position of the first snippet in the given input.
       
  1750      */
       
  1751     private static class CompletionInfoImpl implements CompletionInfo {
       
  1752 
       
  1753         private final Completeness completeness;
       
  1754         private final String source;
       
  1755         private final String remaining;
       
  1756 
       
  1757         CompletionInfoImpl(Completeness completeness, String source, String remaining) {
       
  1758             this.completeness = completeness;
       
  1759             this.source = source;
       
  1760             this.remaining = remaining;
       
  1761         }
       
  1762 
       
  1763         /**
       
  1764          * The analyzed completeness of the input.
       
  1765          *
       
  1766          * @return an enum describing the completeness of the input string.
       
  1767          */
       
  1768         @Override
       
  1769         public Completeness completeness() {
       
  1770             return completeness;
       
  1771         }
       
  1772 
       
  1773         /**
       
  1774          * Input remaining after the complete part of the source.
       
  1775          *
       
  1776          * @return the portion of the input string that remains after the
       
  1777          * complete Snippet
       
  1778          */
       
  1779         @Override
       
  1780         public String remaining() {
       
  1781             return remaining;
       
  1782         }
       
  1783 
       
  1784         /**
       
  1785          * Source code for the first Snippet of code input. For example, first
       
  1786          * statement, or first method declaration. Trailing semicolons will be
       
  1787          * added, as needed.
       
  1788          *
       
  1789          * @return the source of the first encountered Snippet
       
  1790          */
       
  1791         @Override
       
  1792         public String source() {
       
  1793             return source;
       
  1794         }
       
  1795     }
       
  1796 
  1703 }
  1797 }