JET-142 Support string templates:

Make '$' in short entries a separate token
This commit is contained in:
Andrey Breslav
2011-07-12 13:37:18 +04:00
parent 591740717a
commit ee61fa7e10
11 changed files with 471 additions and 441 deletions
@@ -577,7 +577,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
/* /*
* stringTemplateElement * stringTemplateElement
* : RegularStringPart * : RegularStringPart
* : ShortTemplateEntry * : ShortTemplateEntrySTART SimpleName
* : EscapeSequence * : EscapeSequence
* : longTemplate * : longTemplate
* ; * ;
@@ -597,11 +597,12 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // ESCAPE_SEQUENCE advance(); // ESCAPE_SEQUENCE
mark.done(ESCAPE_STRING_TEMPLATE_ENTRY); mark.done(ESCAPE_STRING_TEMPLATE_ENTRY);
} }
else if (at(SHORT_TEMPLATE_ENTRY)) { else if (at(SHORT_TEMPLATE_ENTRY_START)) {
PsiBuilder.Marker entry = mark(); PsiBuilder.Marker entry = mark();
advance(); // SHORT_TEMPLATE_ENTRY_START
PsiBuilder.Marker reference = mark(); PsiBuilder.Marker reference = mark();
advance(); // SHORT_TEMPLATE_ENTRY expect(IDENTIFIER, "Expecting a name");
reference.done(REFERENCE_EXPRESSION); reference.done(REFERENCE_EXPRESSION);
entry.done(SHORT_STRING_TEMPLATE_ENTRY); entry.done(SHORT_STRING_TEMPLATE_ENTRY);
@@ -613,7 +614,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
parseExpression(); parseExpression();
expect(LONG_TEMPLATE_ENTRY_END, "Expecting '}'", TokenSet.create(CLOSING_QUOTE, DANGLING_NEWLINE, REGULAR_STRING_PART, ESCAPE_SEQUENCE, SHORT_TEMPLATE_ENTRY)); expect(LONG_TEMPLATE_ENTRY_END, "Expecting '}'", TokenSet.create(CLOSING_QUOTE, DANGLING_NEWLINE, REGULAR_STRING_PART, ESCAPE_SEQUENCE, SHORT_TEMPLATE_ENTRY_START));
longTemplateEntry.done(LONG_STRING_TEMPLATE_ENTRY); longTemplateEntry.done(LONG_STRING_TEMPLATE_ENTRY);
} }
else { else {
@@ -29,7 +29,7 @@ import java.util.List;
* @author max * @author max
*/ */
public class JetSimpleNameExpression extends JetReferenceExpression { public class JetSimpleNameExpression extends JetReferenceExpression {
public static final TokenSet REFERENCE_TOKENS = TokenSet.orSet(JetTokens.LABELS, TokenSet.create(JetTokens.IDENTIFIER, JetTokens.FIELD_IDENTIFIER, JetTokens.THIS_KEYWORD, JetTokens.SHORT_TEMPLATE_ENTRY)); public static final TokenSet REFERENCE_TOKENS = TokenSet.orSet(JetTokens.LABELS, TokenSet.create(JetTokens.IDENTIFIER, JetTokens.FIELD_IDENTIFIER, JetTokens.THIS_KEYWORD));
public JetSimpleNameExpression(@NotNull ASTNode node) { public JetSimpleNameExpression(@NotNull ASTNode node) {
super(node); super(node);
@@ -42,9 +42,6 @@ public class JetSimpleNameExpression extends JetReferenceExpression {
return null; return null;
} }
String text = referencedNameElement.getNode().getText(); String text = referencedNameElement.getNode().getText();
if (referencedNameElement.getNode().getElementType() == JetTokens.SHORT_TEMPLATE_ENTRY) {
text = text.substring(1); // Strip the '$'
}
if (text.startsWith("`") && text.endsWith("`") && text.length() >= 2) { if (text.startsWith("`") && text.endsWith("`") && text.length() >= 2) {
return text.substring(1, text.length()-1); return text.substring(1, text.length()-1);
} }
@@ -7,7 +7,6 @@ import com.google.common.collect.Sets;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.JetNodeTypes;
@@ -866,7 +865,7 @@ public class JetTypeInferrer {
} }
} }
else { else {
assert TokenSet.create(JetTokens.IDENTIFIER, JetTokens.SHORT_TEMPLATE_ENTRY).contains(expression.getReferencedNameElementType()); assert JetTokens.IDENTIFIER == expression.getReferencedNameElementType();
if (referencedName != null) { if (referencedName != null) {
VariableDescriptor variable = context.scope.getVariable(referencedName); VariableDescriptor variable = context.scope.getVariable(referencedName);
if (variable != null) { if (variable != null) {
+13 -7
View File
@@ -46,8 +46,8 @@ import org.jetbrains.jet.lexer.JetTokens;
%eof{ return; %eof{ return;
%eof} %eof}
%xstate STRING %xstate STRING SHORT_TEMPLATE_ENTRY
%state LONG_TEMPLATE %state LONG_TEMPLATE_ENTRY
DIGIT=[0-9] DIGIT=[0-9]
HEX_DIGIT=[0-9A-Fa-f] HEX_DIGIT=[0-9A-Fa-f]
@@ -117,12 +117,18 @@ LONG_TEMPLATE_ENTRY_END=\}
<STRING> \n { popState(); yypushback(1); return JetTokens.DANGLING_NEWLINE; } <STRING> \n { popState(); yypushback(1); return JetTokens.DANGLING_NEWLINE; }
<STRING> {REGULAR_STRING_PART} { return JetTokens.REGULAR_STRING_PART; } <STRING> {REGULAR_STRING_PART} { return JetTokens.REGULAR_STRING_PART; }
<STRING> {ESCAPE_SEQUENCE} { return JetTokens.ESCAPE_SEQUENCE; } <STRING> {ESCAPE_SEQUENCE} { return JetTokens.ESCAPE_SEQUENCE; }
<STRING> {SHORT_TEMPLATE_ENTRY} { return JetTokens.SHORT_TEMPLATE_ENTRY; } <STRING> {SHORT_TEMPLATE_ENTRY} {
<STRING> {LONELY_DOLLAR} { return JetTokens.REGULAR_STRING_PART; } pushState(SHORT_TEMPLATE_ENTRY);
<STRING> {LONG_TEMPLATE_ENTRY_START} { pushState(LONG_TEMPLATE); return JetTokens.LONG_TEMPLATE_ENTRY_START; } yypushback(yylength() - 1);
return JetTokens.SHORT_TEMPLATE_ENTRY_START;
}
<SHORT_TEMPLATE_ENTRY> {IDENTIFIER} { popState(); return JetTokens.IDENTIFIER; }
<LONG_TEMPLATE> "{" { lBraceCount++; return JetTokens.LBRACE; } <STRING> {LONELY_DOLLAR} { return JetTokens.REGULAR_STRING_PART; }
<LONG_TEMPLATE> "}" { <STRING> {LONG_TEMPLATE_ENTRY_START} { pushState(LONG_TEMPLATE_ENTRY); return JetTokens.LONG_TEMPLATE_ENTRY_START; }
<LONG_TEMPLATE_ENTRY> "{" { lBraceCount++; return JetTokens.LBRACE; }
<LONG_TEMPLATE_ENTRY> "}" {
if (lBraceCount == 0) { if (lBraceCount == 0) {
popState(); popState();
return JetTokens.LONG_TEMPLATE_ENTRY_END; return JetTokens.LONG_TEMPLATE_ENTRY_END;
@@ -25,8 +25,8 @@ public interface JetTokens {
JetToken CLOSING_QUOTE = new JetToken("CLOSING_QUOTE"); JetToken CLOSING_QUOTE = new JetToken("CLOSING_QUOTE");
JetToken OPEN_QUOTE = new JetToken("OPEN_QUOTE"); JetToken OPEN_QUOTE = new JetToken("OPEN_QUOTE");
JetToken REGULAR_STRING_PART = new JetToken("REGULAR_STRING_PART"); JetToken REGULAR_STRING_PART = new JetToken("REGULAR_STRING_PART");
JetToken SHORT_TEMPLATE_ENTRY = new JetToken("SHORT_TEMPLATE_ENTRY");
JetToken ESCAPE_SEQUENCE = new JetToken("ESCAPE_SEQUENCE"); JetToken ESCAPE_SEQUENCE = new JetToken("ESCAPE_SEQUENCE");
JetToken SHORT_TEMPLATE_ENTRY_START = new JetToken("SHORT_TEMPLATE_ENTRY_START");
JetToken LONG_TEMPLATE_ENTRY_START = new JetToken("LONG_TEMPLATE_ENTRY_START"); JetToken LONG_TEMPLATE_ENTRY_START = new JetToken("LONG_TEMPLATE_ENTRY_START");
JetToken LONG_TEMPLATE_ENTRY_END = new JetToken("LONG_TEMPLATE_ENTRY_END"); JetToken LONG_TEMPLATE_ENTRY_END = new JetToken("LONG_TEMPLATE_ENTRY_END");
JetToken DANGLING_NEWLINE = new JetToken("DANGLING_NEWLINE"); JetToken DANGLING_NEWLINE = new JetToken("DANGLING_NEWLINE");
File diff suppressed because it is too large Load Diff
@@ -121,6 +121,7 @@ public class JetHighlighter extends SyntaxHighlighterBase {
keys1.put(JetTokens.REGULAR_STRING_PART, JET_STRING); keys1.put(JetTokens.REGULAR_STRING_PART, JET_STRING);
keys1.put(JetTokens.LONG_TEMPLATE_ENTRY_END, JET_STRING_ESCAPE); keys1.put(JetTokens.LONG_TEMPLATE_ENTRY_END, JET_STRING_ESCAPE);
keys1.put(JetTokens.LONG_TEMPLATE_ENTRY_START, JET_STRING_ESCAPE); keys1.put(JetTokens.LONG_TEMPLATE_ENTRY_START, JET_STRING_ESCAPE);
keys1.put(JetTokens.SHORT_TEMPLATE_ENTRY_START, JET_STRING_ESCAPE);
keys1.put(JetTokens.ESCAPE_SEQUENCE, JET_STRING_ESCAPE); keys1.put(JetTokens.ESCAPE_SEQUENCE, JET_STRING_ESCAPE);
+1 -1
View File
@@ -12,7 +12,7 @@ fun demo() {
"$.$.asdf$\t" "$.$.asdf$\t"
"asd\$" "asd\$"
"asd$a<error>\x</error>" "asd$a<error>\x</error>"
"asd$a$asd$ <error>$xxx</error>" "asd$a$asd$ $<error>xxx</error>"
"fosdfasdo${1 + bar + 100}}sdsdfgdsfsdf" "fosdfasdo${1 + bar + 100}}sdsdfgdsfsdf"
"foo${bar + map {foo}}sdfsdf" "foo${bar + map {foo}}sdfsdf"
"foo${bar + map { "foo" }}sdfsdf" "foo${bar + map { "foo" }}sdfsdf"
+12 -6
View File
@@ -158,15 +158,17 @@ JetFile: StringTemplates.jet
STRING_TEMPLATE STRING_TEMPLATE
PsiElement(OPEN_QUOTE)('"') PsiElement(OPEN_QUOTE)('"')
SHORT_STRING_TEMPLATE_ENTRY SHORT_STRING_TEMPLATE_ENTRY
PsiElement(SHORT_TEMPLATE_ENTRY_START)('$')
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(SHORT_TEMPLATE_ENTRY)('$abc') PsiElement(IDENTIFIER)('abc')
PsiElement(CLOSING_QUOTE)('"') PsiElement(CLOSING_QUOTE)('"')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
STRING_TEMPLATE STRING_TEMPLATE
PsiElement(OPEN_QUOTE)('"') PsiElement(OPEN_QUOTE)('"')
SHORT_STRING_TEMPLATE_ENTRY SHORT_STRING_TEMPLATE_ENTRY
PsiElement(SHORT_TEMPLATE_ENTRY_START)('$')
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(SHORT_TEMPLATE_ENTRY)('$abc') PsiElement(IDENTIFIER)('abc')
ESCAPE_STRING_TEMPLATE_ENTRY ESCAPE_STRING_TEMPLATE_ENTRY
PsiElement(ESCAPE_SEQUENCE)('\"') PsiElement(ESCAPE_SEQUENCE)('\"')
PsiErrorElement:Expecting '"' PsiErrorElement:Expecting '"'
@@ -207,8 +209,9 @@ JetFile: StringTemplates.jet
LITERAL_STRING_TEMPLATE_ENTRY LITERAL_STRING_TEMPLATE_ENTRY
PsiElement(REGULAR_STRING_PART)('asd') PsiElement(REGULAR_STRING_PART)('asd')
SHORT_STRING_TEMPLATE_ENTRY SHORT_STRING_TEMPLATE_ENTRY
PsiElement(SHORT_TEMPLATE_ENTRY_START)('$')
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(SHORT_TEMPLATE_ENTRY)('$a') PsiElement(IDENTIFIER)('a')
PsiElement(CLOSING_QUOTE)('"') PsiElement(CLOSING_QUOTE)('"')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
STRING_TEMPLATE STRING_TEMPLATE
@@ -216,11 +219,13 @@ JetFile: StringTemplates.jet
LITERAL_STRING_TEMPLATE_ENTRY LITERAL_STRING_TEMPLATE_ENTRY
PsiElement(REGULAR_STRING_PART)('asd') PsiElement(REGULAR_STRING_PART)('asd')
SHORT_STRING_TEMPLATE_ENTRY SHORT_STRING_TEMPLATE_ENTRY
PsiElement(SHORT_TEMPLATE_ENTRY_START)('$')
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(SHORT_TEMPLATE_ENTRY)('$a') PsiElement(IDENTIFIER)('a')
SHORT_STRING_TEMPLATE_ENTRY SHORT_STRING_TEMPLATE_ENTRY
PsiElement(SHORT_TEMPLATE_ENTRY_START)('$')
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(SHORT_TEMPLATE_ENTRY)('$asd') PsiElement(IDENTIFIER)('asd')
LITERAL_STRING_TEMPLATE_ENTRY LITERAL_STRING_TEMPLATE_ENTRY
PsiElement(REGULAR_STRING_PART)('$') PsiElement(REGULAR_STRING_PART)('$')
PsiElement(CLOSING_QUOTE)('"') PsiElement(CLOSING_QUOTE)('"')
@@ -342,8 +347,9 @@ JetFile: StringTemplates.jet
LITERAL_STRING_TEMPLATE_ENTRY LITERAL_STRING_TEMPLATE_ENTRY
PsiElement(REGULAR_STRING_PART)('foo') PsiElement(REGULAR_STRING_PART)('foo')
SHORT_STRING_TEMPLATE_ENTRY SHORT_STRING_TEMPLATE_ENTRY
PsiElement(SHORT_TEMPLATE_ENTRY_START)('$')
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(SHORT_TEMPLATE_ENTRY)('$sdf') PsiElement(IDENTIFIER)('sdf')
LONG_STRING_TEMPLATE_ENTRY LONG_STRING_TEMPLATE_ENTRY
PsiElement(LONG_TEMPLATE_ENTRY_START)('${') PsiElement(LONG_TEMPLATE_ENTRY_START)('${')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
+6 -3
View File
@@ -62,8 +62,9 @@ JetFile: Builder.jet
STRING_TEMPLATE STRING_TEMPLATE
PsiElement(OPEN_QUOTE)('"') PsiElement(OPEN_QUOTE)('"')
SHORT_STRING_TEMPLATE_ENTRY SHORT_STRING_TEMPLATE_ENTRY
PsiElement(SHORT_TEMPLATE_ENTRY_START)('$')
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(SHORT_TEMPLATE_ENTRY)('$libs') PsiElement(IDENTIFIER)('libs')
LITERAL_STRING_TEMPLATE_ENTRY LITERAL_STRING_TEMPLATE_ENTRY
PsiElement(REGULAR_STRING_PART)('/groovy-...') PsiElement(REGULAR_STRING_PART)('/groovy-...')
PsiElement(CLOSING_QUOTE)('"') PsiElement(CLOSING_QUOTE)('"')
@@ -108,8 +109,9 @@ JetFile: Builder.jet
STRING_TEMPLATE STRING_TEMPLATE
PsiElement(OPEN_QUOTE)('"') PsiElement(OPEN_QUOTE)('"')
SHORT_STRING_TEMPLATE_ENTRY SHORT_STRING_TEMPLATE_ENTRY
PsiElement(SHORT_TEMPLATE_ENTRY_START)('$')
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(SHORT_TEMPLATE_ENTRY)('$gantHome') PsiElement(IDENTIFIER)('gantHome')
LITERAL_STRING_TEMPLATE_ENTRY LITERAL_STRING_TEMPLATE_ENTRY
PsiElement(REGULAR_STRING_PART)('/lib') PsiElement(REGULAR_STRING_PART)('/lib')
PsiElement(CLOSING_QUOTE)('"') PsiElement(CLOSING_QUOTE)('"')
@@ -209,8 +211,9 @@ JetFile: Builder.jet
STRING_TEMPLATE STRING_TEMPLATE
PsiElement(OPEN_QUOTE)('"') PsiElement(OPEN_QUOTE)('"')
SHORT_STRING_TEMPLATE_ENTRY SHORT_STRING_TEMPLATE_ENTRY
PsiElement(SHORT_TEMPLATE_ENTRY_START)('$')
REFERENCE_EXPRESSION REFERENCE_EXPRESSION
PsiElement(SHORT_TEMPLATE_ENTRY)('$projectHome') PsiElement(IDENTIFIER)('projectHome')
LITERAL_STRING_TEMPLATE_ENTRY LITERAL_STRING_TEMPLATE_ENTRY
PsiElement(REGULAR_STRING_PART)('/antLayout/src') PsiElement(REGULAR_STRING_PART)('/antLayout/src')
PsiElement(CLOSING_QUOTE)('"') PsiElement(CLOSING_QUOTE)('"')
+4 -4
View File
@@ -7,15 +7,15 @@ fun demo() {
~buzz~fun buzz(f : fun () : Any?) : Int = 1 ~buzz~fun buzz(f : fun () : Any?) : Int = 1
~sdf~val sdf = 1 ~sdf~val sdf = 1
~foo~val foo = 3; ~foo~val foo = 3;
"`abc`$abc" "$`abc`abc"
"$" "$"
"$.$.asdf$\t" "$.$.asdf$\t"
"asd\$" "asd\$"
"asd`a`$a" "asd$`a`a"
"asd`a`$a`asd`$asd$" "asd$`a`a$`asd`asd$"
"fosdfasdo${1 + `bar`bar + 100}}sdsdfgdsfsdf" "fosdfasdo${1 + `bar`bar + 100}}sdsdfgdsfsdf"
"foo${`bar`bar + `map`map {`foo`foo}}sdfsdf" "foo${`bar`bar + `map`map {`foo`foo}}sdfsdf"
"foo${`bar`bar + `map`map { "foo" }}sdfsdf" "foo${`bar`bar + `map`map { "foo" }}sdfsdf"
"foo${`bar`bar + `map`map { "foo${`bar`bar + `map`map {
"foo`sdf`$sdf${ `buzz`buzz{}}" }}sdfsdf" "foo$`sdf`sdf${ `buzz`buzz{}}" }}sdfsdf"
} }