use of org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter 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.impl.synthetic.ClosureSyntheticParameter in project intellij-community by JetBrains.
the class ExpressionGenerator method visitReferenceExpression.
@Override
public void visitReferenceExpression(@NotNull GrReferenceExpression referenceExpression) {
final GrExpression qualifier = referenceExpression.getQualifier();
final GroovyResolveResult resolveResult = referenceExpression.advancedResolve();
final PsiElement resolved = resolveResult.getElement();
final String referenceName = referenceExpression.getReferenceName();
if (PsiUtil.isThisOrSuperRef(referenceExpression)) {
writeThisOrSuperRef(referenceExpression, qualifier, referenceName);
return;
}
if (ResolveUtil.isClassReference(referenceExpression)) {
// just delegate to qualifier
LOG.assertTrue(qualifier != null);
qualifier.accept(this);
return;
}
if (resolved instanceof PsiClass) {
builder.append(((PsiClass) resolved).getQualifiedName());
if (PsiUtil.isExpressionUsed(referenceExpression)) {
builder.append(".class");
}
return;
}
//don't try to resolve local vars that are provided my this generator (they are listed in myUsedVarNames)
if (resolved == null && qualifier == null && context.myUsedVarNames.contains(referenceName)) {
builder.append(referenceName);
return;
}
//all refs in script that are not resolved are saved in 'binding' of the script
if (qualifier == null && (resolved == null || resolved instanceof GrBindingVariable || resolved instanceof LightElement && !(resolved instanceof ClosureSyntheticParameter)) && (referenceExpression.getParent() instanceof GrIndexProperty || !(referenceExpression.getParent() instanceof GrCall)) && PsiUtil.getContextClass(referenceExpression) instanceof GroovyScriptClass) {
final GrExpression thisExpr = factory.createExpressionFromText("this", referenceExpression);
thisExpr.accept(this);
builder.append(".getBinding().getProperty(\"").append(referenceExpression.getReferenceName()).append("\")");
return;
}
final IElementType type = referenceExpression.getDotTokenType();
GrExpression qualifierToUse = qualifier;
if (type == GroovyTokenTypes.mMEMBER_POINTER) {
LOG.assertTrue(qualifier != null);
builder.append("new ").append(GroovyCommonClassNames.ORG_CODEHAUS_GROOVY_RUNTIME_METHOD_CLOSURE).append('(');
qualifier.accept(this);
builder.append(", \"").append(referenceName).append("\")");
return;
}
if (type == GroovyTokenTypes.mOPTIONAL_DOT) {
LOG.assertTrue(qualifier != null);
String qualifierName = createVarByInitializer(qualifier);
builder.append('(').append(qualifierName).append(" == null ? null : ");
qualifierToUse = factory.createReferenceExpressionFromText(qualifierName, referenceExpression);
}
if (resolveResult.isInvokedOnProperty()) {
//property-style access to accessor (e.g. qual.prop should be translated to qual.getProp())
LOG.assertTrue(resolved instanceof PsiMethod);
LOG.assertTrue(GroovyPropertyUtils.isSimplePropertyGetter((PsiMethod) resolved));
invokeMethodOn(((PsiMethod) resolved), qualifierToUse, GrExpression.EMPTY_ARRAY, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, resolveResult.getSubstitutor(), referenceExpression);
} else {
if (qualifierToUse != null) {
qualifierToUse.accept(this);
builder.append('.');
}
if (resolved instanceof PsiNamedElement && !(resolved instanceof GrBindingVariable)) {
final String refName = ((PsiNamedElement) resolved).getName();
if (resolved instanceof GrVariable && context.analyzedVars.toWrap((GrVariable) resolved)) {
//this var should be wrapped by groovy.lang.Reference. so we add .get() tail.
builder.append(context.analyzedVars.toVarName((GrVariable) resolved));
if (!PsiUtil.isAccessedForWriting(referenceExpression)) {
builder.append(".get()");
}
} else {
builder.append(refName);
}
} else {
//unresolved reference
if (referenceName != null) {
if (PsiUtil.isAccessedForWriting(referenceExpression)) {
builder.append(referenceName);
} else {
PsiType stringType = PsiType.getJavaLangString(referenceExpression.getManager(), referenceExpression.getResolveScope());
PsiType qualifierType = PsiImplUtil.getQualifierType(referenceExpression);
GroovyResolveResult[] candidates = qualifierType != null ? ResolveUtil.getMethodCandidates(qualifierType, "getProperty", referenceExpression, stringType) : GroovyResolveResult.EMPTY_ARRAY;
final PsiElement method = PsiImplUtil.extractUniqueElement(candidates);
if (method != null) {
builder.append("getProperty(\"").append(referenceName).append("\")");
} else {
builder.append(referenceName);
}
}
} else {
final PsiElement nameElement = referenceExpression.getReferenceNameElement();
if (nameElement instanceof GrExpression) {
((GrExpression) nameElement).accept(this);
} else if (nameElement != null) {
builder.append(nameElement.toString());
}
}
}
}
if (type == GroovyTokenTypes.mOPTIONAL_DOT) {
builder.append(')');
}
}
use of org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter in project intellij-community by JetBrains.
the class GrVariableInplaceRenamer method renameSynthetic.
@Override
protected void renameSynthetic(String newName) {
PsiNamedElement elementToRename = getVariable();
if (elementToRename instanceof ClosureSyntheticParameter && !"it".equals(newName)) {
final GrClosableBlock closure = ((ClosureSyntheticParameter) elementToRename).getClosure();
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
final PsiType type = ((ClosureSyntheticParameter) elementToRename).getTypeGroovy();
final GrParameter newParam = factory.createParameter(newName, TypesUtil.unboxPrimitiveTypeWrapper(type));
final GrParameter added = closure.addParameter(newParam);
JavaCodeStyleManager.getInstance(added.getProject()).shortenClassReferences(added);
}
}
use of org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter in project intellij-community by JetBrains.
the class ReachingDefinitionsCollector method addClosureUsages.
private static void addClosureUsages(final Map<String, VariableInfo> imap, final Map<String, VariableInfo> omap, final GrStatement first, final GrStatement last, GrControlFlowOwner flowOwner) {
flowOwner.accept(new GroovyRecursiveElementVisitor() {
@Override
public void visitClosure(@NotNull GrClosableBlock closure) {
addUsagesInClosure(imap, omap, closure, first, last);
super.visitClosure(closure);
}
private void addUsagesInClosure(final Map<String, VariableInfo> imap, final Map<String, VariableInfo> omap, final GrClosableBlock closure, final GrStatement first, final GrStatement last) {
closure.accept(new GroovyRecursiveElementVisitor() {
@Override
public void visitReferenceExpression(@NotNull GrReferenceExpression refExpr) {
if (refExpr.isQualified()) {
return;
}
PsiElement resolved = refExpr.resolve();
if (!(resolved instanceof GrVariable)) {
return;
}
GrVariable variable = (GrVariable) resolved;
if (PsiTreeUtil.isAncestor(closure, variable, true)) {
return;
}
if (variable instanceof ClosureSyntheticParameter && PsiTreeUtil.isAncestor(closure, ((ClosureSyntheticParameter) variable).getClosure(), false)) {
return;
}
String name = variable.getName();
if (!(variable instanceof GrField)) {
if (!isInFragment(first, last, resolved)) {
if (isInFragment(first, last, closure)) {
addVariable(name, imap, variable.getManager(), variable.getType());
}
} else {
if (!isInFragment(first, last, closure)) {
addVariable(name, omap, variable.getManager(), variable.getType());
}
}
}
}
});
}
});
}
use of org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter in project intellij-community by JetBrains.
the class AbstractClosureParameterEnhancer method getVariableType.
@Override
public final PsiType getVariableType(GrVariable variable) {
if (!(variable instanceof GrParameter)) {
return null;
}
GrClosableBlock closure;
int paramIndex;
if (variable instanceof ClosureSyntheticParameter) {
closure = ((ClosureSyntheticParameter) variable).getClosure();
paramIndex = 0;
} else {
PsiElement eParameterList = variable.getParent();
if (!(eParameterList instanceof GrParameterList))
return null;
PsiElement eClosure = eParameterList.getParent();
if (!(eClosure instanceof GrClosableBlock))
return null;
closure = (GrClosableBlock) eClosure;
GrParameterList parameterList = (GrParameterList) eParameterList;
paramIndex = parameterList.getParameterNumber((GrParameter) variable);
}
PsiType res = getClosureParameterType(closure, paramIndex);
if (res instanceof PsiPrimitiveType) {
return ((PsiPrimitiveType) res).getBoxedType(closure);
}
return res;
}
Aggregations