2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.jetbrains.plugins.groovy.lang.completion;
20 import com.intellij.codeInsight.TailType;
21 import com.intellij.codeInsight.completion.CompletionParameters;
22 import com.intellij.codeInsight.completion.CompletionResultSet;
23 import com.intellij.codeInsight.completion.ModifierChooser;
24 import com.intellij.codeInsight.lookup.LookupElement;
25 import com.intellij.codeInsight.lookup.LookupElementBuilder;
26 import com.intellij.codeInsight.lookup.TailTypeDecorator;
27 import com.intellij.lang.ASTNode;
28 import com.intellij.patterns.PlatformPatterns;
29 import com.intellij.psi.*;
30 import com.intellij.psi.templateLanguages.OuterLanguageElement;
31 import com.intellij.psi.util.PsiTreeUtil;
32 import com.intellij.util.ArrayUtil;
33 import org.jetbrains.annotations.NotNull;
34 import org.jetbrains.plugins.groovy.lang.groovydoc.lexer.GroovyDocTokenTypes;
35 import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocInlinedTag;
36 import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
37 import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
38 import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
39 import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
40 import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
41 import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
42 import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
43 import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
44 import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection;
45 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
46 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
47 import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
48 import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.*;
49 import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
50 import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
51 import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
52 import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition;
53 import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
54 import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner;
55 import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
56 import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
58 import static com.intellij.patterns.PsiJavaPatterns.psiElement;
59 import static com.intellij.patterns.StandardPatterns.or;
64 public class GroovyCompletionData {
65 public static final String[] BUILT_IN_TYPES = {"boolean", "byte", "char", "short", "int", "float", "long", "double", "void"};
66 public static final String[] MODIFIERS = new String[]{"private", "public", "protected", "transient", "abstract", "native", "volatile", "strictfp", "static"};
67 static final String[] INLINED_DOC_TAGS = {"code", "docRoot", "inheritDoc", "link", "linkplain", "literal"};
68 static final String[] DOC_TAGS = {"author", "deprecated", "exception", "param", "return", "see", "serial", "serialData",
69 "serialField", "since", "throws", "version"};
71 public static void addGroovyKeywords(CompletionParameters parameters, CompletionResultSet result) {
72 PsiElement position = parameters.getPosition();
73 PsiElement parent = position.getParent();
74 if (parent instanceof GrLiteral) {
78 if (!PlatformPatterns.psiElement().afterLeaf(".", ".&").accepts(position)) {
79 if (suggestPackage(position)) {
80 result.addElement(keyword(PsiKeyword.PACKAGE, TailType.INSERT_SPACE));
82 if (suggestImport(position)) {
83 result.addElement(keyword(PsiKeyword.IMPORT, TailType.INSERT_SPACE));
86 addTypeDefinitionKeywords(result, position);
87 for (String keyword : addExtendsImplements(position)) {
88 result.addElement(keyword(keyword, TailType.HUMBLE_SPACE));
91 registerControlCompletion(position, result);
93 if (parent instanceof GrExpression) {
94 addKeywords(result, false, PsiKeyword.TRUE, PsiKeyword.FALSE, PsiKeyword.NULL, PsiKeyword.SUPER, PsiKeyword.THIS);
95 result.addElement(keyword(PsiKeyword.NEW, TailType.INSERT_SPACE));
96 result.addElement(keyword("as", TailType.HUMBLE_SPACE));
99 if (isInfixOperatorPosition(position)) {
100 addKeywords(result, true, "in", PsiKeyword.INSTANCEOF);
101 } else if (suggestThrows(position)) {
102 result.addElement(keyword(PsiKeyword.THROWS, TailType.INSERT_SPACE));
103 } else if (suggestPrimitiveTypes(position)) {
104 boolean inCast = psiElement()
105 .afterLeaf(psiElement().withText("(").withParent(psiElement(GrParenthesizedExpression.class, GrTypeCastExpression.class)))
108 addKeywords(result, !inCast, BUILT_IN_TYPES);
111 if (psiElement(GrReferenceExpression.class).inside(or(psiElement(GrWhileStatement.class), psiElement(GrForStatement.class))).accepts(parent)) {
112 addKeywords(result, false, PsiKeyword.BREAK, PsiKeyword.CONTINUE);
114 else if (psiElement(GrReferenceExpression.class).inside(GrCaseSection.class).accepts(parent)) {
115 addKeywords(result, false, PsiKeyword.BREAK);
118 if (psiElement().withSuperParent(2, GrImportStatement.class).accepts(position)) {
119 if (psiElement().afterLeaf(PsiKeyword.IMPORT).accepts(position)) {
120 addKeywords(result, true, PsiKeyword.STATIC);
123 if (suggestModifiers(position)) {
124 addModifiers(position, result);
126 if (psiElement().afterLeaf(MODIFIERS).accepts(position) ||
127 GroovyCompletionUtil.isInTypeDefinitionBody(position) && GroovyCompletionUtil.isNewStatement(position, true)) {
128 addKeywords(result, true, PsiKeyword.SYNCHRONIZED);
130 if (suggestFinalDef(position) || psiElement().afterLeaf(
131 psiElement().withText("(").withParent(GrForStatement.class)).accepts(position)) {
132 addKeywords(result, true, PsiKeyword.FINAL, "def");
138 public static void addModifiers(PsiElement position, CompletionResultSet result) {
139 PsiClass scope = PsiTreeUtil.getParentOfType(position, PsiClass.class);
140 PsiModifierList modifierList = ModifierChooser.findModifierList(position);
141 addKeywords(result, true, ModifierChooser.addMemberModifiers(modifierList, scope != null && scope.isInterface()));
144 private static void addTypeDefinitionKeywords(CompletionResultSet result, PsiElement position) {
145 if (suggestClassInterfaceEnum(position)) {
146 addKeywords(result, true, PsiKeyword.CLASS, PsiKeyword.INTERFACE, PsiKeyword.ENUM);
148 if (afterAtInType(position)) {
149 result.addElement(keyword(PsiKeyword.INTERFACE, TailType.HUMBLE_SPACE));
154 private static String[] addExtendsImplements(PsiElement context) {
155 if (context.getParent() == null) {
156 return ArrayUtil.EMPTY_STRING_ARRAY;
159 PsiElement elem = context.getParent();
160 boolean ext = !(elem instanceof GrExtendsClause);
161 boolean impl = !(elem instanceof GrImplementsClause);
163 if (elem instanceof GrTypeDefinitionBody) { //inner class
164 elem = PsiUtil.skipWhitespaces(context.getPrevSibling(), false);
167 elem = PsiUtil.skipWhitespaces(elem.getPrevSibling(), false);
170 ext &= elem instanceof GrInterfaceDefinition || elem instanceof GrClassDefinition;
171 impl &= elem instanceof GrEnumTypeDefinition || elem instanceof GrClassDefinition;
172 if (!ext && !impl) return ArrayUtil.EMPTY_STRING_ARRAY;
174 PsiElement[] children = elem.getChildren();
175 for (PsiElement child : children) {
176 ext &= !(child instanceof GrExtendsClause);
177 if (child instanceof GrImplementsClause || child instanceof GrTypeDefinitionBody) {
178 return ArrayUtil.EMPTY_STRING_ARRAY;
182 return new String[]{PsiKeyword.EXTENDS, PsiKeyword.IMPLEMENTS};
185 return new String[]{ext ? PsiKeyword.EXTENDS : PsiKeyword.IMPLEMENTS};
188 public static void addKeywords(CompletionResultSet result, boolean space, String... keywords) {
189 for (String s : keywords) {
190 result.addElement(keyword(s, space ? TailType.HUMBLE_SPACE : TailType.NONE));
194 private static LookupElement keyword(final String keyword, @NotNull TailType tail) {
195 LookupElementBuilder element = LookupElementBuilder.create(keyword).setBold();
196 return tail != TailType.NONE ? TailTypeDecorator.withTail(element, tail) : element;
199 private static void registerControlCompletion(PsiElement context, CompletionResultSet result) {
200 String[] controlKeywords = {"try", "while", "with", "switch", "for", "return", "throw", "assert", "synchronized",};
202 if (isControlStructure(context)) {
203 addKeywords(result, true, controlKeywords);
205 if (inCaseSection(context)) {
206 result.addElement(keyword("case", TailType.INSERT_SPACE));
207 result.addElement(keyword("default", TailType.CASE_COLON));
209 if (afterTry(context)) {
210 addKeywords(result, true, "catch", "finally");
212 if (afterIfOrElse(context)) {
213 addKeywords(result, true, "else");
217 public static void addGroovyDocKeywords(CompletionParameters parameters, CompletionResultSet result) {
218 PsiElement position = parameters.getPosition();
219 if (PlatformPatterns.psiElement(GroovyDocTokenTypes.mGDOC_TAG_NAME).andNot(PlatformPatterns.psiElement().afterLeaf(".")).accepts(position)) {
220 String[] tags = position.getParent() instanceof GrDocInlinedTag ? INLINED_DOC_TAGS : DOC_TAGS;
221 for (String docTag : tags) {
222 result.addElement(TailTypeDecorator.withTail(LookupElementBuilder.create(docTag), TailType.INSERT_SPACE));
227 private static boolean suggestPackage(PsiElement context) {
228 if (context.getParent() != null &&
229 !(context.getParent() instanceof PsiErrorElement) &&
230 context.getParent().getParent() instanceof GroovyFile &&
231 ((GroovyFile) context.getParent().getParent()).getPackageDefinition() == null) {
232 if (context.getParent() instanceof GrReferenceExpression) {
235 if (context.getParent() instanceof GrApplicationStatement &&
236 ((GrApplicationStatement) context.getParent()).getExpressionArguments()[0] instanceof GrReferenceExpression) {
241 if (context.getTextRange().getStartOffset() == 0 && !(context instanceof OuterLanguageElement)) {
245 final PsiElement leaf = GroovyCompletionUtil.getLeafByOffset(context.getTextRange().getStartOffset() - 1, context);
247 PsiElement parent = leaf.getParent();
248 if (parent instanceof GroovyFile) {
249 GroovyFile groovyFile = (GroovyFile) parent;
250 if (groovyFile.getPackageDefinition() == null) {
251 return GroovyCompletionUtil.isNewStatement(context, false);
259 private static boolean suggestImport(PsiElement context) {
260 if (context.getParent() != null &&
261 !(context.getParent() instanceof PsiErrorElement) &&
262 GroovyCompletionUtil.isNewStatement(context, false) &&
263 context.getParent().getParent() instanceof GroovyFile) {
266 final PsiElement leaf = GroovyCompletionUtil.getLeafByOffset(context.getTextRange().getStartOffset() - 1, context);
268 PsiElement parent = leaf.getParent();
269 if (parent instanceof GroovyFile) {
270 return GroovyCompletionUtil.isNewStatement(context, false);
273 return context.getTextRange().getStartOffset() == 0 && !(context instanceof OuterLanguageElement);
276 public static boolean suggestClassInterfaceEnum(PsiElement context) {
277 if (suggestThrows(context) || addExtendsImplements(context).length > 0) {
281 PsiElement parent = context.getParent();
282 if (parent instanceof GrTypeDefinitionBody) {
286 if (parent instanceof GrReferenceExpression) {
287 if (parent.getParent() instanceof GroovyFile) {
290 if ((parent.getParent() instanceof GrApplicationStatement ||
291 parent.getParent() instanceof GrCall) &&
292 parent.getParent().getParent() instanceof GroovyFile) {
296 final PsiElement leaf = GroovyCompletionUtil.getLeafByOffset(context.getTextRange().getStartOffset() - 1, context);
298 PsiElement prev = leaf;
299 prev = PsiImplUtil.realPrevious(prev);
300 if (prev instanceof GrModifierList &&
301 prev.getParent() != null &&
302 prev.getParent().getParent() instanceof GroovyFile) {
306 if (leaf.getParent() instanceof GroovyFile) {
307 return GroovyCompletionUtil.isNewStatement(context, false);
314 private static boolean afterAtInType(PsiElement context) {
315 PsiElement previous = PsiImplUtil.realPrevious(context.getPrevSibling());
316 if (previous != null &&
317 GroovyTokenTypes.mAT.equals(previous.getNode().getElementType()) &&
318 context.getParent() != null &&
319 context.getParent().getParent() instanceof GroovyFile) {
322 if (context.getParent() instanceof PsiErrorElement &&
323 context.getParent().getParent() instanceof GrAnnotation) {
329 private static boolean isControlStructure(PsiElement context) {
330 final int offset = context.getTextRange().getStartOffset();
331 PsiElement prevSibling = context.getPrevSibling();
332 if (context.getParent() instanceof GrReferenceElement && prevSibling != null && prevSibling.getNode() != null) {
333 ASTNode node = prevSibling.getNode();
334 return !TokenSets.DOTS.contains(node.getElementType());
336 if (GroovyCompletionUtil.isNewStatement(context, true)) {
337 final PsiElement leaf = GroovyCompletionUtil.getLeafByOffset(offset - 1, context);
338 if (leaf != null && leaf.getParent() instanceof GrStatementOwner) {
343 if (context.getParent() != null) {
344 PsiElement parent = context.getParent();
346 if (parent instanceof GrExpression &&
347 parent.getParent() instanceof GroovyFile) {
351 if (parent instanceof GrReferenceExpression) {
353 PsiElement superParent = parent.getParent();
354 if (superParent instanceof GrExpression) {
355 superParent = superParent.getParent();
358 if (superParent instanceof GrStatementOwner ||
359 superParent instanceof GrIfStatement ||
360 superParent instanceof GrForStatement ||
361 superParent instanceof GrWhileStatement) {
372 private static boolean inCaseSection(PsiElement context) {
373 if (context.getParent() instanceof GrReferenceExpression &&
374 context.getParent().getParent() instanceof GrCaseSection) {
377 final PsiElement left = GroovyCompletionUtil.nearestLeftSibling(context);
378 if (left != null && left.getParent() != null &&
379 left.getParent() instanceof GrSwitchStatement &&
380 left.getPrevSibling() != null &&
381 left.getPrevSibling().getNode() != null &&
382 GroovyTokenTypes.mLCURLY.equals(left.getPrevSibling().getNode().getElementType())) {
388 private static boolean afterTry(PsiElement context) {
389 if (context != null &&
390 GroovyCompletionUtil.nearestLeftSibling(context) instanceof GrTryCatchStatement) {
391 GrTryCatchStatement tryStatement = (GrTryCatchStatement) GroovyCompletionUtil.nearestLeftSibling(context);
392 if (tryStatement == null) return false;
393 if (tryStatement.getFinallyClause() == null) {
397 if (context != null &&
398 GroovyCompletionUtil.nearestLeftSibling(context) instanceof PsiErrorElement &&
399 GroovyCompletionUtil.nearestLeftSibling(context).getPrevSibling() instanceof GrTryCatchStatement) {
400 GrTryCatchStatement tryStatement = (GrTryCatchStatement) GroovyCompletionUtil.nearestLeftSibling(context).getPrevSibling();
401 if (tryStatement == null) return false;
402 if (tryStatement.getFinallyClause() == null) {
406 if (context != null &&
407 (context.getParent() instanceof GrReferenceExpression || context.getParent() instanceof PsiErrorElement) &&
408 GroovyCompletionUtil.nearestLeftSibling(context.getParent()) instanceof GrTryCatchStatement) {
409 GrTryCatchStatement tryStatement = (GrTryCatchStatement) GroovyCompletionUtil.nearestLeftSibling(context.getParent());
410 if (tryStatement == null) return false;
411 if (tryStatement.getFinallyClause() == null) {
418 private static boolean afterIfOrElse(PsiElement context) {
419 if (context.getParent() != null &&
420 GroovyCompletionUtil.nearestLeftSibling(context.getParent()) instanceof GrIfStatement) {
423 if (context.getParent() != null &&
424 GroovyCompletionUtil.nearestLeftSibling(context) != null &&
425 GroovyCompletionUtil.nearestLeftSibling(context).getPrevSibling() instanceof GrIfStatement) {
426 GrIfStatement statement = (GrIfStatement) GroovyCompletionUtil.nearestLeftSibling(context).getPrevSibling();
427 if (statement.getElseBranch() == null) {
431 if (context.getParent() != null &&
432 context.getParent().getParent() instanceof GrCommandArgumentList &&
433 context.getParent().getParent().getParent().getParent() instanceof GrIfStatement) {
434 GrIfStatement statement = (GrIfStatement) context.getParent().getParent().getParent().getParent();
435 if (statement.getElseBranch() == null) {
442 private static boolean suggestThrows(PsiElement context) {
443 PsiElement candidate = null;
444 if (GroovyCompletionUtil.isInTypeDefinitionBody(context)) {
445 PsiElement run = context;
446 while(!(run.getParent() instanceof GrTypeDefinitionBody)) {
447 run = run.getParent();
450 candidate = PsiTreeUtil.getPrevSiblingOfType(run, GrMember.class);
452 else if (context.getParent() instanceof PsiErrorElement) {
453 candidate = context.getParent().getPrevSibling();
456 return candidate instanceof GrMethod && ((GrMethod) candidate).getBlock() == null;
459 private static boolean suggestPrimitiveTypes(PsiElement context) {
460 final PsiElement parent = context.getParent();
461 if (parent == null) return false;
463 PsiElement previous = PsiImplUtil.realPrevious(parent.getPrevSibling());
464 if (parent instanceof GrReferenceElement && parent.getParent() instanceof GrArgumentList) {
465 PsiElement prevSibling = context.getPrevSibling();
466 if (prevSibling != null && prevSibling.getNode() != null) {
467 if (!TokenSets.DOTS.contains(prevSibling.getNode().getElementType())) {
470 } else if (!(previous != null && GroovyTokenTypes.mAT.equals(previous.getNode().getElementType()))) {
476 if (previous != null && GroovyTokenTypes.mAT.equals(previous.getNode().getElementType())) {
479 if (GroovyCompletionUtil.asSimpleVariable(context) ||
480 GroovyCompletionUtil.asTypedMethod(context) ||
481 GroovyCompletionUtil.asVariableInBlock(context)) {
484 if ((parent instanceof GrParameter &&
485 ((GrParameter)parent).getTypeElementGroovy() == null) ||
486 parent instanceof GrReferenceElement &&
487 !(parent.getParent() instanceof GrImportStatement) &&
488 !(parent.getParent() instanceof GrPackageDefinition) &&
489 !(parent.getParent() instanceof GrArgumentList)) {
490 PsiElement prevSibling = context.getPrevSibling();
491 if (parent instanceof GrReferenceElement && prevSibling != null && prevSibling.getNode() != null) {
492 ASTNode node = prevSibling.getNode();
493 return !TokenSets.DOTS.contains(node.getElementType());
498 if (PsiImplUtil.realPrevious(parent.getPrevSibling()) instanceof GrModifierList) {
501 if (PsiImplUtil.realPrevious(context.getPrevSibling()) instanceof GrModifierList) {
504 return parent instanceof GrExpression &&
505 parent.getParent() instanceof GroovyFile &&
506 GroovyCompletionUtil.isNewStatement(context, false);
509 private static boolean isInfixOperatorPosition(PsiElement context) {
510 if (context.getParent() != null &&
511 context.getParent() instanceof GrReferenceExpression &&
512 context.getParent().getParent() != null &&
513 context.getParent().getParent() instanceof GrCommandArgumentList) {
516 if (GroovyCompletionUtil.nearestLeftSibling(context) instanceof PsiErrorElement &&
517 GroovyCompletionUtil.endsWithExpression(GroovyCompletionUtil.nearestLeftSibling(context).getPrevSibling())) {
520 if (context.getParent() instanceof PsiErrorElement) {
521 PsiElement leftSibling = GroovyCompletionUtil.nearestLeftSibling(context.getParent());
522 if (leftSibling != null && leftSibling.getLastChild() instanceof GrExpression) {
526 if (context.getParent() instanceof GrReferenceExpression &&
527 GroovyCompletionUtil.nearestLeftSibling(context.getParent()) instanceof PsiErrorElement &&
528 GroovyCompletionUtil.endsWithExpression(GroovyCompletionUtil.nearestLeftSibling(context.getParent()).getPrevSibling())) {
531 if (context.getParent() instanceof PsiErrorElement &&
532 GroovyCompletionUtil.endsWithExpression(GroovyCompletionUtil.nearestLeftSibling(context.getParent()))) {
539 private static boolean suggestModifiers(PsiElement context) {
540 if (GroovyCompletionUtil.asSimpleVariable(context) || GroovyCompletionUtil.asTypedMethod(context)) {
543 if (GroovyCompletionUtil.isFirstElementAfterPossibleModifiersInVariableDeclaration(context, false) &&
544 !psiElement().afterLeaf("def").accepts(context)) {
548 if (psiElement().afterLeaf(MODIFIERS).accepts(context) || psiElement().afterLeaf("synchronized").accepts(context)) {
552 final PsiElement contextParent = context.getParent();
553 if (contextParent instanceof GrReferenceElement && contextParent.getParent() instanceof GrTypeElement) {
554 PsiElement parent = contextParent.getParent().getParent();
555 if (parent instanceof GrVariableDeclaration &&
556 (parent.getParent() instanceof GrTypeDefinitionBody || parent.getParent() instanceof GroovyFile) || parent instanceof GrMethod) {
560 if (contextParent instanceof GrField) {
561 final GrVariable variable = (GrVariable)contextParent;
562 if (variable.getTypeElementGroovy() == null) {
566 if (contextParent instanceof GrExpression &&
567 contextParent.getParent() instanceof GroovyFile &&
568 GroovyCompletionUtil.isNewStatement(context, false)) {
571 if (context.getTextRange().getStartOffset() == 0 && !(context instanceof OuterLanguageElement)) {
574 final PsiElement leaf = GroovyCompletionUtil.getLeafByOffset(context.getTextRange().getStartOffset() - 1, context);
575 if (leaf != null && GroovyCompletionUtil.isNewStatement(context, false)) {
576 PsiElement parent = leaf.getParent();
577 if (parent instanceof GroovyFile) {
581 return contextParent instanceof GrExpression &&
582 contextParent.getParent() instanceof GrApplicationStatement &&
583 contextParent.getParent().getParent() instanceof GroovyFile &&
584 GroovyCompletionUtil.isNewStatement(context, false);
587 public static boolean suggestFinalDef(PsiElement context) {
588 if (GroovyCompletionUtil.asSimpleVariable(context) ||
589 GroovyCompletionUtil.asTypedMethod(context) ||
590 GroovyCompletionUtil.asVariableInBlock(context)) {
593 if ((context.getParent() instanceof GrParameter &&
594 ((GrParameter) context.getParent()).getTypeElementGroovy() == null) ||
595 context.getParent() instanceof GrReferenceElement &&
596 !(context.getParent() instanceof GrReferenceExpression) &&
597 !(context.getParent().getParent() instanceof GrImportStatement) &&
598 !(context.getParent().getParent() instanceof GrPackageDefinition)) {
601 if (PsiImplUtil.realPrevious(context.getParent().getPrevSibling()) instanceof GrModifierList) {
604 if (PsiImplUtil.realPrevious(context.getPrevSibling()) instanceof GrModifierList) {
607 return context.getParent() instanceof GrExpression &&
608 context.getParent().getParent() instanceof GroovyFile &&
609 GroovyCompletionUtil.isNewStatement(context, false);