use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock 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.blocks.GrClosableBlock in project intellij-community by JetBrains.
the class GroovyEnterHandler method preprocessEnter.
@Override
public Result preprocessEnter(@NotNull PsiFile file, @NotNull Editor editor, @NotNull Ref<Integer> caretOffset, @NotNull Ref<Integer> caretAdvance, @NotNull DataContext dataContext, EditorActionHandler originalHandler) {
Document document = editor.getDocument();
Project project = file.getProject();
CaretModel caretModel = editor.getCaretModel();
if (!(file instanceof GroovyFileBase)) {
return Result.Continue;
}
int docLength = document.getTextLength();
if (docLength == 0) {
return Result.Continue;
}
final int caret = caretModel.getOffset();
final EditorHighlighter highlighter = ((EditorEx) editor).getHighlighter();
if (caret >= 1 && caret < docLength && CodeInsightSettings.getInstance().SMART_INDENT_ON_ENTER) {
HighlighterIterator iterator = highlighter.createIterator(caret);
iterator.retreat();
while (!iterator.atEnd() && TokenType.WHITE_SPACE == iterator.getTokenType()) {
iterator.retreat();
}
boolean afterArrow = !iterator.atEnd() && iterator.getTokenType() == GroovyTokenTypes.mCLOSABLE_BLOCK_OP;
if (afterArrow) {
originalHandler.execute(editor, dataContext);
PsiDocumentManager.getInstance(project).commitDocument(document);
CodeStyleManager.getInstance(project).adjustLineIndent(file, caretModel.getOffset());
}
iterator = highlighter.createIterator(caretModel.getOffset());
while (!iterator.atEnd() && TokenType.WHITE_SPACE == iterator.getTokenType()) {
iterator.advance();
}
if (!iterator.atEnd() && GroovyTokenTypes.mRCURLY == iterator.getTokenType()) {
PsiDocumentManager.getInstance(project).commitDocument(document);
final PsiElement element = file.findElementAt(iterator.getStart());
if (element != null && element.getNode().getElementType() == GroovyTokenTypes.mRCURLY && element.getParent() instanceof GrClosableBlock && docLength > caret && afterArrow) {
return Result.DefaultForceIndent;
}
}
if (afterArrow) {
return Result.Stop;
}
if (editor.isInsertMode() && !HandlerUtils.isReadOnly(editor) && !editor.getSelectionModel().hasSelection() && handleFlyingGeese(editor, caret, dataContext, originalHandler, file)) {
return Result.DefaultForceIndent;
}
}
if (handleEnter(editor, dataContext, project, originalHandler))
return Result.Stop;
return Result.Continue;
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock in project intellij-community by JetBrains.
the class MakeClosureCallExplicitIntention method processIntention.
@Override
public void processIntention(@NotNull PsiElement element, @NotNull Project project, Editor editor) throws IncorrectOperationException {
final GrMethodCallExpression expression = (GrMethodCallExpression) element;
final GrExpression invokedExpression = expression.getInvokedExpression();
final GrArgumentList argList = expression.getArgumentList();
final GrClosableBlock[] closureArgs = expression.getClosureArguments();
final StringBuilder newExpression = new StringBuilder();
newExpression.append(invokedExpression.getText());
newExpression.append(".call");
newExpression.append(argList.getText());
for (GrClosableBlock closureArg : closureArgs) {
newExpression.append(closureArg.getText());
}
PsiImplUtil.replaceExpression(newExpression.toString(), expression);
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock in project intellij-community by JetBrains.
the class MavenGroovyPolyglotPomMemberContributor method processDynamicElements.
@Override
public void processDynamicElements(@NotNull PsiType qualifierType, PsiClass aClass, @NotNull PsiScopeProcessor processor, @NotNull PsiElement place, @NotNull ResolveState state) {
if (!(aClass instanceof GroovyScriptClass)) {
return;
}
PsiFile file = aClass.getContainingFile();
if (file == null || !"pom.groovy".equals(file.getName()))
return;
List<String> methodCallInfo = MavenGroovyPomUtil.getGroovyMethodCalls(place);
MultiMap<String, String> multiMap = MultiMap.createLinked();
MultiMap<String, String> leafMap = MultiMap.createLinked();
String key = StringUtil.join(methodCallInfo, "->");
for (Contributor contributor : contributors.getValue()) {
contributor.populate(place.getProject(), multiMap, leafMap);
}
for (String classSource : multiMap.get(key)) {
DynamicMemberUtils.process(processor, false, place, classSource);
}
for (String classSource : leafMap.get(key)) {
if (!(place.getParent() instanceof GrClosableBlock)) {
DynamicMemberUtils.process(processor, false, place, classSource);
}
}
if (!methodCallInfo.isEmpty() && StringUtil.endsWithIgnoreCase(ContainerUtil.getLastItem(methodCallInfo), CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED)) {
key = StringUtil.join(ContainerUtil.dropTail(methodCallInfo), "->");
for (String classSource : multiMap.get(key)) {
DynamicMemberUtils.process(processor, false, place, classSource);
}
}
}
use of org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock in project intellij-community by JetBrains.
the class AnonymousFromMapGenerator method writeAnonymousMap.
static void writeAnonymousMap(GrListOrMap operand, GrTypeElement typeElement, final StringBuilder builder, ExpressionContext context) {
final PsiType type = typeElement.getType();
final PsiClass psiClass;
final PsiSubstitutor substitutor;
if (type instanceof PsiClassType) {
final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType) type).resolveGenerics();
psiClass = resolveResult.getElement();
substitutor = resolveResult.getSubstitutor();
} else {
psiClass = null;
substitutor = PsiSubstitutor.EMPTY;
}
builder.append("new ");
TypeWriter.writeTypeForNew(builder, type, operand);
builder.append("() {\n");
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(operand.getProject());
final GrExpression caller = factory.createExpressionFromText("this");
for (GrNamedArgument arg : operand.getNamedArguments()) {
final String name = arg.getLabelName();
final GrExpression expression = arg.getExpression();
if (name == null || expression == null || !(expression instanceof GrClosableBlock))
continue;
final GrClosableBlock closure = (GrClosableBlock) expression;
final GrParameter[] allParameters = closure.getAllParameters();
List<GrParameter> actual = new ArrayList<>(Arrays.asList(allParameters));
final PsiType clReturnType = context.typeProvider.getReturnType(closure);
GrExpression[] args = new GrExpression[allParameters.length];
for (int i = 0; i < allParameters.length; i++) {
args[i] = factory.createExpressionFromText(allParameters[i].getName());
}
for (int param = allParameters.length; param >= 0; param--) {
if (param < allParameters.length && !actual.get(param).isOptional())
continue;
if (param < allParameters.length) {
final GrParameter opt = actual.remove(param);
args[param] = opt.getInitializerGroovy();
}
final GrParameter[] parameters = actual.toArray(new GrParameter[actual.size()]);
final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(parameters, clReturnType);
final GrMethod pattern = factory.createMethodFromSignature(name, signature);
PsiMethod found = null;
if (psiClass != null) {
found = psiClass.findMethodBySignature(pattern, true);
}
if (found != null) {
ModifierListGenerator.writeModifiers(builder, found.getModifierList(), ModifierListGenerator.JAVA_MODIFIERS_WITHOUT_ABSTRACT);
} else {
builder.append("public ");
}
PsiType returnType;
if (found != null) {
returnType = substitutor.substitute(context.typeProvider.getReturnType(found));
} else {
returnType = signature.getReturnType();
}
TypeWriter.writeType(builder, returnType, operand);
builder.append(' ').append(name);
GenerationUtil.writeParameterList(builder, parameters, new GeneratorClassNameProvider(), context);
final ExpressionContext extended = context.extend();
extended.setInAnonymousContext(true);
if (param == allParameters.length) {
new CodeBlockGenerator(builder, extended).generateCodeBlock(allParameters, closure, false);
} else {
builder.append("{\n");
final ExpressionGenerator expressionGenerator = new ExpressionGenerator(builder, extended);
GenerationUtil.invokeMethodByName(caller, name, args, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, expressionGenerator, arg);
builder.append(";\n}\n");
}
}
}
builder.append("}");
}
Aggregations