IDEA-70787 Groovy: Method call don't resolve if method name is a string literal.

This commit is contained in:
Maxim Medvedev
2011-06-08 21:53:12 +04:00
parent e60cb5cdff
commit 28df3a62cf
10 changed files with 87 additions and 27 deletions
@@ -50,10 +50,19 @@ public class PathExpression implements GroovyElementTypes {
*/
public static Result parsePathExprQualifierForExprStatement(PsiBuilder builder, GroovyParser parser) {
PsiBuilder.Marker marker = builder.mark();
final IElementType qualifierType = PrimaryExpression.parsePrimaryExpression(builder, parser);
final PsiBuilder.Marker marker1 = builder.mark();
IElementType qualifierType = PrimaryExpression.parsePrimaryExpression(builder, parser);
if (qualifierType != WRONGWAY) {
Result result;
if (isPathElementStart(builder)) {
if (builder.getTokenType() == mLPAREN && qualifierType == LITERAL) {
marker1.rollbackTo();
qualifierType = PrimaryExpression.parsePrimaryExpression(builder, parser, true);
assert qualifierType != WRONGWAY;
}
else {
marker1.drop();
}
PsiBuilder.Marker newMarker = marker.precede();
marker.drop();
if (checkForLCurly(builder)) {
@@ -67,12 +76,14 @@ public class PathExpression implements GroovyElementTypes {
}
}
else {
marker1.drop();
marker.drop();
result = INVOKED_EXPR;
}
return result;
}
else {
marker1.drop();
marker.drop();
return WRONG_WAY;
}
@@ -36,47 +36,56 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
*/
public class PrimaryExpression implements GroovyElementTypes {
public static IElementType parsePrimaryExpression(PsiBuilder builder, GroovyParser parser) {
if (TokenSets.BUILT_IN_TYPE.contains(builder.getTokenType())) {
public static IElementType parsePrimaryExpression(PsiBuilder builder, GroovyParser parser) {
return parsePrimaryExpression(builder, parser, false);
}
public static IElementType parsePrimaryExpression(PsiBuilder builder, GroovyParser parser, boolean literalsAsRefExprs) {
final IElementType tokenType = builder.getTokenType();
if (TokenSets.BUILT_IN_TYPE.contains(tokenType)) {
ParserUtils.eatElement(builder, BUILT_IN_TYPE_EXPRESSION);
return BUILT_IN_TYPE_EXPRESSION;
}
if (kTHIS == builder.getTokenType()) {
if (kTHIS == tokenType) {
ParserUtils.eatElement(builder, THIS_REFERENCE_EXPRESSION);
return THIS_REFERENCE_EXPRESSION;
}
if (kSUPER == builder.getTokenType()) {
if (kSUPER == tokenType) {
ParserUtils.eatElement(builder, SUPER_REFERENCE_EXPRESSION);
return SUPER_REFERENCE_EXPRESSION;
}
if (kNEW == builder.getTokenType()) {
if (kNEW == tokenType) {
return newExprParse(builder, parser);
}
if (mIDENT == builder.getTokenType()) {
if (mIDENT == tokenType) {
ParserUtils.eatElement(builder, REFERENCE_EXPRESSION);
return REFERENCE_EXPRESSION;
}
if (mGSTRING_BEGIN == builder.getTokenType()) {
if (mGSTRING_BEGIN == tokenType) {
return StringConstructorExpression.parse(builder, parser);
}
if (mREGEX_BEGIN == builder.getTokenType()) {
if (mREGEX_BEGIN == tokenType) {
return RegexConstructorExpression.parse(builder, parser);
}
if (mLBRACK == builder.getTokenType()) {
if (mLBRACK == tokenType) {
return ListOrMapConstructorExpression.parse(builder, parser);
}
if (mLPAREN == builder.getTokenType()) {
if (mLPAREN == tokenType) {
return parenthesizedExprParse(builder, parser);
}
if (mLCURLY == builder.getTokenType()) {
if (mLCURLY == tokenType) {
return OpenOrClosableBlock.parseClosableBlock(builder, parser);
}
if (TokenSets.CONSTANTS.contains(builder.getTokenType())) {
ParserUtils.eatElement(builder, LITERAL);
return LITERAL;
if (tokenType == mSTRING_LITERAL ||
tokenType == mGSTRING_LITERAL ||
tokenType == mREGEX_LITERAL) {
return ParserUtils.eatElement(builder, literalsAsRefExprs ? REFERENCE_EXPRESSION : LITERAL);
}
if (mWRONG_REGEX_LITERAL == builder.getTokenType()) {
if (TokenSets.CONSTANTS.contains(tokenType)) {
return ParserUtils.eatElement(builder, LITERAL);
}
if (mWRONG_REGEX_LITERAL == tokenType) {
PsiBuilder.Marker marker = builder.mark();
builder.advanceLexer();
builder.error(GroovyBundle.message("wrong.string"));
@@ -35,17 +35,6 @@ public class StringConstructorExpression implements GroovyElementTypes {
Marker sMarker = builder.mark();
if (ParserUtils.getToken(builder, mGSTRING_BEGIN)) {
ParserUtils.getToken(builder, mGSTRING_CONTENT);
if (mGSTRING_END.equals(builder.getTokenType())) {
sMarker.rollbackTo();
sMarker = builder.mark();
builder.advanceLexer();
builder.advanceLexer();
builder.advanceLexer();
sMarker.done(LITERAL);
return LITERAL;
}
while (ParserUtils.getToken(builder, mGSTRING_CONTENT) || mDOLLAR.equals(builder.getTokenType())) {
if (mDOLLAR.equals(builder.getTokenType())) {
stringConstructorValuePart(builder, parser);
@@ -281,4 +281,7 @@ public class ExpressionsParsingTest extends GroovyParsingTestCase {
public void testcommandExpr$keywords() {doTest()}
public void testDiamond() {doTest()}
void testpath$stringMethodCall1() {doTest()}
void testpath$stringMethodCall2() {doTest()}
}
@@ -713,4 +713,16 @@ class Foo {
PsiReference ref = configureByFile("staticImportInSamePackage/A.groovy", "A.groovy");
assertNotNull(ref.resolve())
}
void testStringRefExpr1() {
assertNotNull(resolve("a.groovy"));
}
void testStringRefExpr2() {
assertNotNull(resolve("a.groovy"));
}
void testStringRefExpr3() {
assertNotNull(resolve("a.groovy"));
}
}
@@ -0,0 +1,9 @@
'foo'()
-----
Groovy script
Method call
Reference expression
PsiElement(string)(''foo'')
Arguments
PsiElement(()('(')
PsiElement())(')')
@@ -0,0 +1,18 @@
'foo'.substring(0, 1)
-----
Groovy script
Method call
Reference expression
Literal
PsiElement(string)(''foo'')
PsiElement(.)('.')
PsiElement(identifier)('substring')
Arguments
PsiElement(()('(')
Literal
PsiElement(Integer)('0')
PsiElement(,)(',')
PsiWhiteSpace(' ')
Literal
PsiElement(Integer)('1')
PsiElement())(')')
@@ -0,0 +1,3 @@
def foo(){}
'f<ref>oo'()
@@ -0,0 +1,3 @@
def foo(){}
"f<ref>oo"()
@@ -0,0 +1,3 @@
def 'foo bar'(){}
'f<ref>oo bar'()