Fixing declarative hints lexer and parser after the marks introduction. marks
authorJan Lahoda <jlahoda@netbeans.org>
Sat, 22 Jan 2011 19:28:36 +0100
branchmarks
changeset 5264fde0197d631
parent 522 e0beda79deac
child 527 a19f2108d439
Fixing declarative hints lexer and parser after the marks introduction.
file/src/org/netbeans/modules/jackpot30/file/DeclarativeHintLexer.java
file/src/org/netbeans/modules/jackpot30/file/DeclarativeHintsParser.java
file/test/unit/src/org/netbeans/modules/jackpot30/file/DeclarativeHintsParserTest.java
     1.1 --- a/file/src/org/netbeans/modules/jackpot30/file/DeclarativeHintLexer.java	Wed Jan 19 18:56:40 2011 +0100
     1.2 +++ b/file/src/org/netbeans/modules/jackpot30/file/DeclarativeHintLexer.java	Sat Jan 22 19:28:36 2011 +0100
     1.3 @@ -87,10 +87,36 @@
     1.4          }
     1.5  
     1.6          while (read != LexerInput.EOF) {
     1.7 -            Matcher identifierMatcher = IDENTIFIER_RE.matcher(input.readText());
     1.8 +            if (input.readLength() > 1) {
     1.9 +                String inputString = input.readText().toString();
    1.10 +                
    1.11 +                for (Entry<String, DeclarativeHintTokenId> e : BLOCK_TOKEN_START.entrySet()) {
    1.12 +                    if (!inputString.substring(0, inputString.length() - 1).endsWith(e.getKey()))
    1.13 +                        continue;
    1.14  
    1.15 -            if (identifierMatcher.find()) {
    1.16 -                int start = identifierMatcher.start();
    1.17 +                    input.backup(1);
    1.18 +                    
    1.19 +                    Token<DeclarativeHintTokenId> preread = resolvePrereadText(e.getKey().length(), whitespaceLength);
    1.20 +
    1.21 +                    if (preread != null) {
    1.22 +                        return preread;
    1.23 +                    }
    1.24 +
    1.25 +                    return readBlockToken(e.getValue(), BLOCK_TOKEN_END.get(e.getValue()));
    1.26 +                }
    1.27 +                
    1.28 +                Token<DeclarativeHintTokenId> t = testToken(inputString, whitespaceLength, false);
    1.29 +
    1.30 +                if (t != null) {
    1.31 +                    return t;
    1.32 +                }
    1.33 +
    1.34 +            }
    1.35 +
    1.36 +            Matcher variableMatcher = IDENTIFIER_RE.matcher(input.readText());
    1.37 +
    1.38 +            if (variableMatcher.find()) {
    1.39 +                int start = variableMatcher.start();
    1.40  
    1.41                  if (start == 0) {
    1.42                      Matcher m;
    1.43 @@ -104,13 +130,12 @@
    1.44                          input.backup(1);
    1.45                      }
    1.46  
    1.47 -                    m = IDENTIFIER_RE.matcher(input.readText());
    1.48 -                    m.find();
    1.49 -                    
    1.50 -                    if (m.group(0).startsWith("$")) {
    1.51 +                    String image = input.readText().toString();
    1.52 +
    1.53 +                    if (image.startsWith("$")) {
    1.54                          return fact.createToken(DeclarativeHintTokenId.VARIABLE);
    1.55 -                    } else if (TOKENS.containsKey(m.group(0))) {
    1.56 -                        return fact.createToken(TOKENS.get(m.group(0)));
    1.57 +                    } else if (TOKENS.containsKey(image)) {
    1.58 +                        return fact.createToken(TOKENS.get(image));
    1.59                      } else {
    1.60                          return fact.createToken(DeclarativeHintTokenId.IDENTIFIER);
    1.61                      }
    1.62 @@ -123,25 +148,13 @@
    1.63  
    1.64                  input.backup(input.readLength() - start);
    1.65  
    1.66 -                Token<DeclarativeHintTokenId> t = readTokenOrBlockToken(whitespaceLength, true);
    1.67 -
    1.68 -                if (t != null) {
    1.69 -                    return t;
    1.70 -                }
    1.71 -
    1.72                  return fact.createToken(DeclarativeHintTokenId.JAVA_SNIPPET);
    1.73              }
    1.74  
    1.75 -            Token<DeclarativeHintTokenId> t = readTokenOrBlockToken(whitespaceLength, false);
    1.76 -
    1.77 -            if (t != null) {
    1.78 -                return t;
    1.79 -             }
    1.80 -
    1.81              read = input.read();
    1.82          }
    1.83  
    1.84 -        Token<DeclarativeHintTokenId> t = testToken(input.readText().toString(), whitespaceLength, true, false);
    1.85 +        Token<DeclarativeHintTokenId> t = testToken(input.readText().toString(), whitespaceLength, true);
    1.86  
    1.87          if (t != null) {
    1.88              return t;
    1.89 @@ -156,7 +169,7 @@
    1.90  
    1.91      public void release() {}
    1.92  
    1.93 -    private Token<DeclarativeHintTokenId> testToken(String toTest, int whitespaceLength, boolean eof, boolean noRealEof) {
    1.94 +    private Token<DeclarativeHintTokenId> testToken(String toTest, int whitespaceLength, boolean eof) {
    1.95          if (toTest.length() < 2 && !eof) return null;
    1.96  
    1.97          DeclarativeHintTokenId id = null;
    1.98 @@ -235,32 +248,8 @@
    1.99          return fact.createToken(tokenId);
   1.100      }
   1.101  
   1.102 -    private Token<DeclarativeHintTokenId> readTokenOrBlockToken(int whitespaceLength, boolean eofLike) {
   1.103 -        String inputString = input.readText().toString();
   1.104 -
   1.105 -        Token t = testToken(inputString, whitespaceLength, eofLike, eofLike);
   1.106 -
   1.107 -        if (t != null) {
   1.108 -            return t;
   1.109 -        }
   1.110 -
   1.111 -        for (Entry<String, DeclarativeHintTokenId> e : BLOCK_TOKEN_START.entrySet()) {
   1.112 -            if (!inputString.endsWith(e.getKey()))
   1.113 -                continue;
   1.114 -
   1.115 -            Token<DeclarativeHintTokenId> preread = resolvePrereadText(e.getKey().length(), whitespaceLength);
   1.116 -
   1.117 -            if (preread != null) {
   1.118 -                return preread;
   1.119 -            }
   1.120 -
   1.121 -            return readBlockToken(e.getValue(), BLOCK_TOKEN_END.get(e.getValue()));
   1.122 -        }
   1.123 -
   1.124 -        return null;
   1.125 -    }
   1.126 -
   1.127 -    private static final Pattern IDENTIFIER_RE = Pattern.compile("([A-Za-z_$][A-Za-z0-9_$]*)");
   1.128 +    private static final Pattern DISPLAY_NAME_RE = Pattern.compile("'[^']*':");
   1.129 +    private static final Pattern IDENTIFIER_RE = Pattern.compile("[A-Za-z_$][A-Za-z0-9_$]*");
   1.130  
   1.131      private static final Map<String, DeclarativeHintTokenId> TOKENS;
   1.132      private static final Map<String, DeclarativeHintTokenId> BLOCK_TOKEN_START;
     2.1 --- a/file/src/org/netbeans/modules/jackpot30/file/DeclarativeHintsParser.java	Wed Jan 19 18:56:40 2011 +0100
     2.2 +++ b/file/src/org/netbeans/modules/jackpot30/file/DeclarativeHintsParser.java	Sat Jan 22 19:28:36 2011 +0100
     2.3 @@ -144,6 +144,25 @@
     2.4          return false;
     2.5      }
     2.6  
     2.7 +    private boolean moveNext() {
     2.8 +        if (input.moveNext()) return true;
     2.9 +
    2.10 +        eof = true;
    2.11 +
    2.12 +        return false;
    2.13 +    }
    2.14 +
    2.15 +    private boolean skipWhitespaces() {
    2.16 +        while (id() == WHITESPACE || id() == BLOCK_COMMENT || id() == LINE_COMMENT) {
    2.17 +            if (!input.moveNext()) {
    2.18 +                eof = true;
    2.19 +                return false;
    2.20 +            }
    2.21 +        }
    2.22 +
    2.23 +        return true;
    2.24 +    }
    2.25 +
    2.26      private boolean eof;
    2.27  
    2.28      private Token<DeclarativeHintTokenId> token() {
    2.29 @@ -197,7 +216,7 @@
    2.30          input.moveStart();
    2.31          eof = false;
    2.32          
    2.33 -        while (nextToken()) {
    2.34 +        while (moveNext()) {
    2.35              if (id() == JAVA_BLOCK) {
    2.36                  continue;
    2.37              }
    2.38 @@ -208,8 +227,12 @@
    2.39      }
    2.40  
    2.41      private void parseRule() {
    2.42 +        int patternStart = input.offset();
    2.43 +        skipWhitespaces();
    2.44 +        
    2.45          String displayName = parseDisplayName();
    2.46 -        int patternStart = input.offset();
    2.47 +
    2.48 +        if (displayName != null) patternStart = input.offset();
    2.49          
    2.50          readUntil(LEADS_TO, DOUBLE_COLON, DOUBLE_SEMICOLON, OPTIONS);
    2.51  
    2.52 @@ -234,11 +257,15 @@
    2.53          List<FixTextDescription> targets = new LinkedList<FixTextDescription>();
    2.54  
    2.55          while (id() == LEADS_TO && !eof) {
    2.56 -            nextToken();
    2.57 +            moveNext();
    2.58 +
    2.59 +            int targetStart = input.offset();
    2.60 +
    2.61 +            skipWhitespaces();
    2.62  
    2.63              String fixDisplayName = parseDisplayName();
    2.64  
    2.65 -            int targetStart = input.offset();
    2.66 +            if (fixDisplayName != null) targetStart = input.offset();
    2.67  
    2.68              readUntil(LEADS_TO, DOUBLE_COLON, DOUBLE_SEMICOLON, OPTIONS);
    2.69  
    2.70 @@ -300,11 +327,13 @@
    2.71                  //XXX: report an error
    2.72                  return ;
    2.73              }
    2.74 -            
    2.75 -            nextToken();
    2.76 +
    2.77 +            input.moveNext();
    2.78  
    2.79              int typeStart = input.offset();
    2.80  
    2.81 +            skipWhitespaces();
    2.82 +
    2.83              readUntil(LEADS_TO, AND, DOUBLE_SEMICOLON);
    2.84  
    2.85              int typeEnd = input.offset();
    2.86 @@ -362,7 +391,7 @@
    2.87                  if (input.token().id() == DeclarativeHintTokenId.COLON) {
    2.88                      String displayName = t.text().subSequence(1, t.text().length() - 1).toString();
    2.89  
    2.90 -                    nextToken();
    2.91 +                    input.moveNext();
    2.92                      return displayName;
    2.93                  } else {
    2.94                      input.movePrevious();
     3.1 --- a/file/test/unit/src/org/netbeans/modules/jackpot30/file/DeclarativeHintsParserTest.java	Wed Jan 19 18:56:40 2011 +0100
     3.2 +++ b/file/test/unit/src/org/netbeans/modules/jackpot30/file/DeclarativeHintsParserTest.java	Sat Jan 22 19:28:36 2011 +0100
     3.3 @@ -116,7 +116,7 @@
     3.4          m.put("$1", ParameterKind.VARIABLE);
     3.5  
     3.6          performTest("'test': $1 + $2 :: test(\"a\", $2, $1) => 1 + 1;;",
     3.7 -                    StringHintDescription.create("$1 + $2 ")
     3.8 +                    StringHintDescription.create(" $1 + $2 ")
     3.9                                           .addCondition(new MethodInvocation(false, "test", m, null))
    3.10                                           .addTos(" 1 + 1")
    3.11                                           .setDisplayName("test"));
    3.12 @@ -130,7 +130,7 @@
    3.13          m.put("javax.lang.model.SourceVersion.RELEASE_6", ParameterKind.ENUM_CONSTANT);
    3.14  
    3.15          performTest("'test': $1 + $2 :: test($1, Modifier.VOLATILE, SourceVersion.RELEASE_6) => 1 + 1;;",
    3.16 -                    StringHintDescription.create("$1 + $2 ")
    3.17 +                    StringHintDescription.create(" $1 + $2 ")
    3.18                                           .addCondition(new MethodInvocation(false, "test", m, null))
    3.19                                           .addTos(" 1 + 1")
    3.20                                           .setDisplayName("test"));
    3.21 @@ -144,7 +144,7 @@
    3.22          m.put("javax.lang.model.SourceVersion.RELEASE_6", ParameterKind.ENUM_CONSTANT);
    3.23  
    3.24          performTest("'test': $1 + $2 :: !test($1, Modifier.VOLATILE, SourceVersion.RELEASE_6) => 1 + 1;;",
    3.25 -                    StringHintDescription.create("$1 + $2 ")
    3.26 +                    StringHintDescription.create(" $1 + $2 ")
    3.27                                           .addCondition(new MethodInvocation(true, "test", m, null))
    3.28                                           .addTos(" 1 + 1")
    3.29                                           .setDisplayName("test"));
    3.30 @@ -152,11 +152,11 @@
    3.31  
    3.32      public void testComments1() throws Exception {
    3.33          performTest("/**/'test': /**/1 /**/+ 1//\n =>/**/ 1 + 1/**/;; //\n'test2': /**/1 + 1 =>//\n 1/**/ + 1;;",
    3.34 -                    StringHintDescription.create("1 /**/+ 1//\n ")
    3.35 -                                         .addTos(" 1 + 1/**/")
    3.36 +                    StringHintDescription.create(" /**/1 /**/+ 1//\n ")
    3.37 +                                         .addTos("/**/ 1 + 1/**/")
    3.38                                           .setDisplayName("test"),
    3.39 -                    StringHintDescription.create("1 + 1 ")
    3.40 -                                         .addTos(" 1/**/ + 1")
    3.41 +                    StringHintDescription.create(" /**/1 + 1 ")
    3.42 +                                         .addTos("//\n 1/**/ + 1")
    3.43                                           .setDisplayName("test2"));
    3.44      }
    3.45  
    3.46 @@ -186,7 +186,7 @@
    3.47          m.put("$1", ParameterKind.VARIABLE);
    3.48  
    3.49          performTest("'test': $1 + $2 => 1 + 1 :: test(\"a\", $2, $1);;",
    3.50 -                    StringHintDescription.create("$1 + $2 ")
    3.51 +                    StringHintDescription.create(" $1 + $2 ")
    3.52                                           .addTos(new StringFixDescription(" 1 + 1 ")
    3.53                                                   .addCondition(new MethodInvocation(false, "test", m, null)))
    3.54                                           .setDisplayName("test"));
    3.55 @@ -229,7 +229,7 @@
    3.56                      Collections.singletonMap("key", "value"),
    3.57                      null,
    3.58                      Collections.singletonList(
    3.59 -                        StringHintDescription.create("$1 + $2 ")
    3.60 +                        StringHintDescription.create(" $1 + $2 ")
    3.61                                               .addTos(new StringFixDescription(" 1 + 1 ")
    3.62                                                       .addCondition(new MethodInvocation(false, "test", m, null))
    3.63                                                       .addOption("key2", "value2"))
    3.64 @@ -247,13 +247,13 @@
    3.65  
    3.66      public void testError1() throws Exception {
    3.67          performErrorGatheringTest("$a + $b :: unknown($a, $b);;",
    3.68 -                                  "0:10-0:26:error:Cannot resolve method");
    3.69 +                                  "0:11-0:26:error:Cannot resolve method");
    3.70      }
    3.71  
    3.72      public void testError2() throws Exception {
    3.73          performErrorGatheringTest("$a + $b :: sourceVersionGE(Foo.BAR);;",
    3.74                                    "0:27-0:34:error:Cannot resolve enum constant",
    3.75 -                                  "0:10-0:35:error:Cannot resolve method");
    3.76 +                                  "0:11-0:35:error:Cannot resolve method");
    3.77      }
    3.78  
    3.79      public void testVarArgs1() throws Exception {