mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[groovy] more precise ambiguous block check (IDEA-148160)
This commit is contained in:
+20
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -92,6 +92,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.modifiers.GrAnnotationCollector;
|
||||
@@ -393,12 +394,25 @@ public class GroovyAnnotator extends GroovyElementVisitor {
|
||||
@Override
|
||||
public void visitTypeDefinitionBody(GrTypeDefinitionBody typeDefinitionBody) {
|
||||
final PsiElement parent = typeDefinitionBody.getParent();
|
||||
if (parent instanceof GrAnonymousClassDefinition) {
|
||||
final PsiElement prev = typeDefinitionBody.getPrevSibling();
|
||||
if (PsiUtil.isLineFeed(prev)) {
|
||||
myHolder.createErrorAnnotation(typeDefinitionBody, GroovyBundle.message("ambiguous.code.block"));
|
||||
}
|
||||
if (!(parent instanceof GrAnonymousClassDefinition)) return;
|
||||
|
||||
final PsiElement prev = typeDefinitionBody.getPrevSibling();
|
||||
if (!PsiUtil.isLineFeed(prev)) return;
|
||||
|
||||
final PsiElement newExpression = parent.getParent();
|
||||
if (!(newExpression instanceof GrNewExpression)) return;
|
||||
|
||||
final GrStatementOwner statementOwner = PsiTreeUtil.getParentOfType(newExpression, GrStatementOwner.class);
|
||||
|
||||
final GrParenthesizedExpression parenthesizedExpression = PsiTreeUtil.getParentOfType(newExpression, GrParenthesizedExpression.class);
|
||||
if (parenthesizedExpression != null && PsiTreeUtil.isAncestor(statementOwner, parenthesizedExpression, true)) return;
|
||||
|
||||
final GrArgumentList argumentList = PsiTreeUtil.getParentOfType(newExpression, GrArgumentList.class);
|
||||
if (argumentList != null && !(argumentList instanceof GrCommandArgumentList)) {
|
||||
if (PsiTreeUtil.isAncestor(statementOwner, argumentList, true)) return;
|
||||
}
|
||||
|
||||
myHolder.createErrorAnnotation(typeDefinitionBody, GroovyBundle.message("ambiguous.code.block"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+153
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -1002,14 +1002,160 @@ class Sub<W extends Window> extends Super<W> {
|
||||
''')
|
||||
}
|
||||
|
||||
void testAnonymousBodyOnNewLine() {
|
||||
testHighlighting('''\
|
||||
class Foo{}
|
||||
print new Foo()
|
||||
void 'test anonymous body on new line within parenthesized expression'() {
|
||||
testHighlighting '''\
|
||||
class Foo {
|
||||
def i
|
||||
}
|
||||
|
||||
def foo = new Foo()
|
||||
<error descr="Ambiguous code block">{
|
||||
String toString() {'abc'}
|
||||
}</error>
|
||||
''')
|
||||
|
||||
def bar = (new Foo()
|
||||
{
|
||||
})
|
||||
|
||||
def baz
|
||||
baz = new Foo()
|
||||
<error descr="Ambiguous code block">{
|
||||
}</error>
|
||||
|
||||
baz = (new Foo()
|
||||
{
|
||||
})
|
||||
|
||||
(baz = new Foo()
|
||||
{
|
||||
})
|
||||
|
||||
new Foo()
|
||||
<error descr="Ambiguous code block">{
|
||||
}</error>
|
||||
|
||||
(new Foo()
|
||||
{
|
||||
})
|
||||
|
||||
new Foo()
|
||||
<error descr="Ambiguous code block">{
|
||||
}</error> + 666
|
||||
|
||||
(new Foo()
|
||||
{
|
||||
}) + 444
|
||||
|
||||
1 + (new Foo()
|
||||
{
|
||||
} + 555)
|
||||
|
||||
(1 + new Foo()
|
||||
{
|
||||
} + 112)
|
||||
|
||||
new Foo()
|
||||
<error descr="Ambiguous code block">{
|
||||
}</error>.getI()
|
||||
|
||||
(new Foo()
|
||||
{
|
||||
}).getI()
|
||||
|
||||
(new Foo()
|
||||
{
|
||||
}.getI())
|
||||
|
||||
def mm() {
|
||||
new Foo()
|
||||
<error descr="Ambiguous code block">{
|
||||
}</error>
|
||||
}
|
||||
|
||||
def mm2() {
|
||||
(new Foo()
|
||||
{
|
||||
})
|
||||
}
|
||||
|
||||
def mm3() {
|
||||
return new Foo()
|
||||
<error descr="Ambiguous code block">{
|
||||
}</error>
|
||||
}
|
||||
|
||||
def mm4() {
|
||||
return (new Foo()
|
||||
{
|
||||
})
|
||||
}
|
||||
|
||||
(new Foo()
|
||||
{
|
||||
def foo() {
|
||||
// still error
|
||||
new Foo()
|
||||
<error descr="Ambiguous code block">{
|
||||
}</error>
|
||||
}
|
||||
})
|
||||
'''
|
||||
}
|
||||
|
||||
void 'test anonymous body on new line within argument list'() {
|
||||
testHighlighting '''\
|
||||
class Foo {}
|
||||
|
||||
def foo(param) {}
|
||||
|
||||
foo(new Foo()
|
||||
{
|
||||
})
|
||||
|
||||
def baz
|
||||
foo(baz = new Foo()
|
||||
{
|
||||
})
|
||||
|
||||
foo(new Foo()
|
||||
{
|
||||
} + 666)
|
||||
|
||||
foo(1 + new Foo()
|
||||
{
|
||||
})
|
||||
|
||||
foo(1 + new Foo()
|
||||
{
|
||||
} + 666)
|
||||
|
||||
foo(new Foo()
|
||||
{
|
||||
}.getI())
|
||||
|
||||
foo(new Foo()
|
||||
{
|
||||
|
||||
}.identity { it })
|
||||
|
||||
foo new Foo()
|
||||
<error descr="Ambiguous code block">{
|
||||
|
||||
}</error>
|
||||
|
||||
foo 1 + (new Foo()
|
||||
{
|
||||
}) + 22
|
||||
|
||||
foo(new Foo() {
|
||||
def a() {
|
||||
// still error
|
||||
new Foo()
|
||||
<error descr="Ambiguous code block">{
|
||||
|
||||
}</error>
|
||||
}
|
||||
})
|
||||
'''
|
||||
}
|
||||
|
||||
void testGenerics() {
|
||||
|
||||
Reference in New Issue
Block a user