use of org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression in project intellij-community by JetBrains.
the class GroovyCodeFragmentFactory method externalParameters.
public static Pair<Map<String, String>, GroovyFile> externalParameters(String text, @NotNull final PsiElement context) {
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.getProject());
final GroovyFile toEval = factory.createGroovyFile(text, false, context);
final GrClosableBlock closure = PsiTreeUtil.getParentOfType(context, GrClosableBlock.class);
final Map<String, String> parameters = new THashMap<>();
final Map<GrExpression, String> replacements = new HashMap<>();
toEval.accept(new GroovyRecursiveElementVisitor() {
@Override
public void visitReferenceExpression(@NotNull GrReferenceExpression referenceExpression) {
super.visitReferenceExpression(referenceExpression);
if (PsiUtil.isThisReference(referenceExpression) || PsiUtil.isSuperReference(referenceExpression)) {
replaceWithReference(referenceExpression, "delegate");
return;
}
PsiElement resolved = referenceExpression.resolve();
if (resolved instanceof PsiMember && (resolved instanceof PsiClass || ((PsiMember) resolved).hasModifierProperty(PsiModifier.STATIC))) {
String qName = com.intellij.psi.util.PsiUtil.getMemberQualifiedName((PsiMember) resolved);
if (qName != null && qName.contains(".") && !referenceExpression.isQualified()) {
replaceWithReference(referenceExpression, qName);
return;
}
}
if (shouldDelegate(referenceExpression, resolved)) {
replaceWithReference(referenceExpression, "delegate." + referenceExpression.getReferenceName());
return;
}
if (resolved instanceof GrVariable && !(resolved instanceof GrField) && !PsiTreeUtil.isAncestor(toEval, resolved, false)) {
final String name = ((GrVariable) resolved).getName();
if (resolved instanceof ClosureSyntheticParameter && PsiTreeUtil.isAncestor(toEval, ((ClosureSyntheticParameter) resolved).getClosure(), false)) {
return;
}
if (resolved instanceof GrBindingVariable && !PsiTreeUtil.isAncestor(resolved.getContainingFile(), toEval, false)) {
return;
}
String value;
if (closure != null && PsiTreeUtil.findCommonParent(resolved, closure) != closure && !(resolved instanceof ClosureSyntheticParameter)) {
// Evaluating inside closure for outer variable definitions
// All non-local variables are accessed by references
value = "this." + name;
} else {
value = name;
}
parameters.put(name, value);
return;
}
if (resolved instanceof PsiLocalVariable || resolved instanceof PsiParameter && !(resolved instanceof GrParameter)) {
String name = referenceExpression.getReferenceName();
parameters.put(name, name);
}
}
private boolean shouldDelegate(GrReferenceExpression referenceExpression, @Nullable PsiElement resolved) {
if (referenceExpression.isQualified()) {
return false;
}
if (resolved instanceof GrField) {
return true;
}
if (resolved instanceof PsiMethod) {
String methodName = ((PsiMethod) resolved).getName();
if (closure != null && "getDelegate".equals(methodName) || "call".equals(methodName)) {
return true;
}
}
return closure != null && resolved instanceof GrLightVariable && "owner".equals(((GrLightVariable) resolved).getName());
}
private void replaceWithReference(GrExpression expr, final String exprText) {
replacements.put(expr, exprText);
}
@Override
public void visitCodeReferenceElement(@NotNull GrCodeReferenceElement refElement) {
super.visitCodeReferenceElement(refElement);
if (refElement.getQualifier() == null) {
PsiElement resolved = refElement.resolve();
if (resolved instanceof PsiClass) {
String qName = ((PsiClass) resolved).getQualifiedName();
if (qName != null) {
int dotIndex = qName.lastIndexOf(".");
if (dotIndex < 0)
return;
String packageName = qName.substring(0, dotIndex);
refElement.setQualifier(factory.createReferenceElementFromText(packageName));
}
}
}
}
});
for (GrExpression expression : replacements.keySet()) {
expression.replaceWithExpression(factory.createExpressionFromText(replacements.get(expression)), false);
}
return Pair.create(parameters, toEval);
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression in project intellij-community by JetBrains.
the class GroovyEditorTextProvider method getEditorText.
@Override
public TextWithImports getEditorText(PsiElement elementAtCaret) {
String result = "";
PsiElement element = findExpressionInner(elementAtCaret, true);
if (element != null) {
if (element instanceof GrReferenceExpression) {
final GrReferenceExpression reference = (GrReferenceExpression) element;
if (reference.getQualifier() == null) {
final PsiElement resolved = reference.resolve();
if (resolved instanceof PsiEnumConstant) {
final PsiEnumConstant enumConstant = (PsiEnumConstant) resolved;
final PsiClass enumClass = enumConstant.getContainingClass();
if (enumClass != null) {
result = enumClass.getName() + "." + enumConstant.getName();
}
}
}
}
if (result.isEmpty()) {
result = element.getText();
}
}
return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, result);
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression in project intellij-community by JetBrains.
the class GroovyEnterHandler method handleInString.
private static boolean handleInString(Editor editor, int caretOffset, DataContext dataContext, EditorActionHandler originalHandler) {
Project project = CommonDataKeys.PROJECT.getData(dataContext);
if (project == null)
return false;
final VirtualFile vfile = FileDocumentManager.getInstance().getFile(editor.getDocument());
assert vfile != null;
PsiFile file = PsiManager.getInstance(project).findFile(vfile);
Document document = editor.getDocument();
String fileText = document.getText();
if (fileText.length() == caretOffset)
return false;
if (!checkStringApplicable(editor, caretOffset))
return false;
if (file == null)
return false;
PsiDocumentManager.getInstance(project).commitDocument(document);
final PsiElement stringElement = inferStringPair(file, caretOffset);
if (stringElement == null)
return false;
ASTNode node = stringElement.getNode();
final IElementType nodeElementType = node.getElementType();
boolean isInsertIndent = isInsertIndent(caretOffset, stringElement.getTextRange().getStartOffset(), fileText);
// For simple String literals like 'abc'
CaretModel caretModel = editor.getCaretModel();
if (nodeElementType == GroovyTokenTypes.mSTRING_LITERAL) {
if (isSingleQuoteString(stringElement)) {
//the case of print '\<caret>'
if (isSlashBeforeCaret(caretOffset, fileText)) {
EditorModificationUtil.insertStringAtCaret(editor, "\n");
} else if (stringElement.getParent() instanceof GrReferenceExpression) {
TextRange range = stringElement.getTextRange();
convertEndToMultiline(range.getEndOffset(), document, fileText, '\'');
document.insertString(range.getStartOffset(), "''");
caretModel.moveToOffset(caretOffset + 2);
EditorModificationUtil.insertStringAtCaret(editor, "\n");
} else {
EditorModificationUtil.insertStringAtCaret(editor, "'+");
originalHandler.execute(editor, dataContext);
EditorModificationUtil.insertStringAtCaret(editor, "'");
PsiDocumentManager.getInstance(project).commitDocument(document);
CodeStyleManager.getInstance(project).reformatRange(file, caretOffset, caretModel.getOffset());
}
} else {
insertLineFeedInString(editor, dataContext, originalHandler, isInsertIndent);
}
return true;
}
if (GSTRING_TOKENS.contains(nodeElementType) || nodeElementType == GroovyElementTypes.GSTRING_CONTENT && GSTRING_TOKENS.contains(node.getFirstChildNode().getElementType()) || nodeElementType == GroovyTokenTypes.mDOLLAR && node.getTreeParent().getTreeParent().getElementType() == GroovyElementTypes.GSTRING) {
PsiElement parent = stringElement.getParent();
if (nodeElementType == GroovyTokenTypes.mGSTRING_LITERAL) {
parent = stringElement;
} else {
while (parent != null && !(parent instanceof GrLiteral)) {
parent = parent.getParent();
}
}
if (parent == null)
return false;
if (isDoubleQuotedString(parent)) {
PsiElement exprSibling = stringElement.getNextSibling();
boolean rightFromDollar = exprSibling instanceof GrExpression && exprSibling.getTextRange().getStartOffset() == caretOffset;
if (rightFromDollar)
caretOffset--;
TextRange parentRange = parent.getTextRange();
if (rightFromDollar || parent.getParent() instanceof GrReferenceExpression) {
convertEndToMultiline(parent.getTextRange().getEndOffset(), document, fileText, '"');
document.insertString(parentRange.getStartOffset(), "\"\"");
caretModel.moveToOffset(caretOffset + 2);
EditorModificationUtil.insertStringAtCaret(editor, "\n");
if (rightFromDollar) {
caretModel.moveCaretRelatively(1, 0, false, false, true);
}
} else if (isSlashBeforeCaret(caretOffset, fileText)) {
EditorModificationUtil.insertStringAtCaret(editor, "\n");
} else {
EditorModificationUtil.insertStringAtCaret(editor, "\"+");
originalHandler.execute(editor, dataContext);
EditorModificationUtil.insertStringAtCaret(editor, "\"");
PsiDocumentManager.getInstance(project).commitDocument(document);
CodeStyleManager.getInstance(project).reformatRange(file, caretOffset, caretModel.getOffset());
}
} else {
insertLineFeedInString(editor, dataContext, originalHandler, isInsertIndent);
}
return true;
}
if (REGEX_TOKENS.contains(nodeElementType) || nodeElementType == GroovyElementTypes.GSTRING_CONTENT && REGEX_TOKENS.contains(node.getFirstChildNode().getElementType()) || nodeElementType == GroovyTokenTypes.mDOLLAR && node.getTreeParent().getTreeParent().getElementType() == GroovyElementTypes.REGEX) {
PsiElement parent = stringElement.getParent();
if (nodeElementType == GroovyTokenTypes.mREGEX_LITERAL || nodeElementType == GroovyTokenTypes.mDOLLAR_SLASH_REGEX_LITERAL) {
parent = stringElement;
} else {
while (parent != null && !(parent instanceof GrLiteral)) {
parent = parent.getParent();
}
}
if (parent == null || parent.getLastChild() instanceof PsiErrorElement)
return false;
PsiElement exprSibling = stringElement.getNextSibling();
boolean rightFromDollar = exprSibling instanceof GrExpression && exprSibling.getTextRange().getStartOffset() == caretOffset;
if (rightFromDollar) {
caretModel.moveToOffset(caretOffset - 1);
}
insertLineFeedInString(editor, dataContext, originalHandler, isInsertIndent);
if (rightFromDollar) {
caretModel.moveCaretRelatively(1, 0, false, false, true);
}
return true;
}
return false;
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression in project intellij-community by JetBrains.
the class GroovyChangeContextUtil method encodeContextInfo.
public static void encodeContextInfo(PsiElement element, PsiElement scope) {
if (!(element instanceof GroovyPsiElement))
return;
if (PsiUtil.isThisReference(element)) {
GrReferenceExpression thisExpr = (GrReferenceExpression) element;
final PsiClass containingClass = PsiTreeUtil.getParentOfType(thisExpr, PsiClass.class);
element.putCopyableUserData(KEY_ENCODED, KEY_ENCODED);
thisExpr.putCopyableUserData(QUALIFIER_CLASS_KEY, containingClass);
} else if (element instanceof GrReferenceExpression) {
GrReferenceExpression refExpr = (GrReferenceExpression) element;
final GrExpression qualifier = refExpr.getQualifierExpression();
if (qualifier == null) {
PsiElement refElement = refExpr.resolve();
element.putCopyableUserData(KEY_ENCODED, KEY_ENCODED);
if (refElement != null && !PsiTreeUtil.isContextAncestor(scope, refElement, false)) {
if (refElement instanceof GrAccessorMethod)
refElement = ((GrAccessorMethod) refElement).getProperty();
if (refElement instanceof PsiClass) {
refExpr.putCopyableUserData(REF_TO_CLASS, (PsiClass) refElement);
} else if (refElement instanceof PsiMember) {
refExpr.putCopyableUserData(REF_TO_MEMBER, (PsiMember) refElement);
}
}
}
} else if (element instanceof GrCodeReferenceElement) {
final PsiElement resolvedElement = ((GrCodeReferenceElement) element).resolve();
element.putCopyableUserData(KEY_ENCODED, KEY_ENCODED);
if (resolvedElement instanceof PsiClass && !PsiTreeUtil.isContextAncestor(scope, resolvedElement, false)) {
element.putCopyableUserData(REF_TO_CLASS, (PsiClass) resolvedElement);
}
}
for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
encodeContextInfo(child, scope);
}
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression in project intellij-community by JetBrains.
the class GantMemberContributor method processDynamicElements.
@Override
public void processDynamicElements(@NotNull PsiType qualifierType, PsiClass aClass, @NotNull PsiScopeProcessor processor, @NotNull PsiElement place, @NotNull ResolveState state) {
if (aClass != null && ClassUtil.getSuperClassesWithCache(aClass).containsKey("groovy.util.AntBuilder")) {
processAntTasks(processor, place, state);
return;
}
if (!(place instanceof GrReferenceExpression) || ((GrReferenceExpression) place).isQualified()) {
return;
}
GrClosableBlock closure = PsiTreeUtil.getContextOfType(place, GrClosableBlock.class, true);
boolean antTasksProcessed = false;
while (closure != null) {
final PsiElement parent = closure.getParent();
if (parent instanceof GrMethodCall) {
final PsiMethod method = ((GrMethodCall) parent).resolveMethod();
if (method instanceof AntBuilderMethod) {
antTasksProcessed = true;
if (!processAntTasks(processor, place, state)) {
return;
}
if (!((AntBuilderMethod) method).processNestedElements(processor)) {
return;
}
break;
}
}
closure = PsiTreeUtil.getContextOfType(closure, GrClosableBlock.class, true);
}
// ------- gant-specific
PsiFile file = place.getContainingFile();
if (file == null || !GroovyScriptUtil.isSpecificScriptFile(file, GantScriptType.INSTANCE)) {
return;
}
if (aClass instanceof GroovyScriptClass) {
for (GrArgumentLabel label : GantUtils.getScriptTargets((GroovyFile) file)) {
final String targetName = label.getName();
if (targetName != null) {
final PsiNamedElement variable = new LightVariableBuilder(targetName, GroovyCommonClassNames.GROOVY_LANG_CLOSURE, label).setBaseIcon(JetgroovyIcons.Groovy.Gant_target);
if (!ResolveUtil.processElement(processor, variable, state)) {
return;
}
}
}
}
if (!antTasksProcessed) {
processAntTasks(processor, place, state);
}
}
Aggregations