use of com.intellij.psi.tree.IElementType 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 com.intellij.psi.tree.IElementType in project intellij-community by JetBrains.
the class ExpressionGenerator method visitBuiltinTypeClassExpression.
@Override
public void visitBuiltinTypeClassExpression(@NotNull GrBuiltinTypeClassExpression expression) {
PsiElement firstChild = expression.getFirstChild();
LOG.assertTrue(firstChild != null);
ASTNode node = firstChild.getNode();
LOG.assertTrue(node != null);
final IElementType type = node.getElementType();
final String boxed = TypesUtil.getBoxedTypeName(type);
builder.append(boxed);
if (expression.getParent() instanceof GrIndexProperty) {
builder.append("[]");
}
builder.append(".class");
}
use of com.intellij.psi.tree.IElementType in project intellij-community by JetBrains.
the class ExpressionGenerator method visitAssignmentExpression.
/**
* x= expr ->
* x = expr
* x.set(expr)[: x.get()]
* x+= expr ->
* x+=expr
* x= plus(x, expr)
* x.set(plus(x, expr))[expr]
* x[a] = 4 ->
* x[a] = 4
* x.putAt(a, 4) [4]
*/
@Override
public void visitAssignmentExpression(@NotNull final GrAssignmentExpression expression) {
final GrExpression lValue = expression.getLValue();
final GrExpression rValue = expression.getRValue();
final IElementType token = expression.getOperationTokenType();
PsiElement realLValue = PsiUtil.skipParentheses(lValue, false);
if (realLValue instanceof GrReferenceExpression && rValue != null) {
GroovyResolveResult resolveResult = ((GrReferenceExpression) realLValue).advancedResolve();
PsiElement resolved = resolveResult.getElement();
if (resolved instanceof GrVariable && context.analyzedVars.toWrap((GrVariable) resolved)) {
//write assignment to wrapped local var
writeAssignmentWithRefSetter((GrExpression) realLValue, expression);
return;
} else if (resolved instanceof PsiMethod && resolveResult.isInvokedOnProperty()) {
//write assignment via setter
writeAssignmentWithSetter(((GrReferenceExpression) realLValue).getQualifier(), (PsiMethod) resolved, expression);
return;
} else if (resolved == null || resolved instanceof GrBindingVariable) {
//write unresolved reference assignment via setter GroovyObject.setProperty(String name, Object value)
final GrExpression qualifier = ((GrReferenceExpression) realLValue).getQualifier();
final PsiType type = PsiImplUtil.getQualifierType((GrReferenceExpression) realLValue);
final GrExpression[] args = { factory.createExpressionFromText("\"" + ((GrReferenceExpression) realLValue).getReferenceName() + "\""), getRValue(expression) };
GroovyResolveResult[] candidates = type != null ? ResolveUtil.getMethodCandidates(type, "setProperty", expression, args[0].getType(), args[1].getType()) : GroovyResolveResult.EMPTY_ARRAY;
final PsiMethod method = PsiImplUtil.extractUniqueElement(candidates);
if (method != null) {
writeAssignmentWithSetter(qualifier, method, args, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, PsiSubstitutor.EMPTY, expression);
return;
}
}
} else if (realLValue instanceof GrIndexProperty) {
//qualifier[args] = rValue
//write assignment via qualifier.putAt(Args, Value) method
final GroovyResolveResult result = PsiImplUtil.extractUniqueResult(((GrIndexProperty) realLValue).multiResolve(false));
final PsiElement resolved = result.getElement();
if (resolved instanceof PsiMethod) {
final GrExpression[] args = ((GrIndexProperty) realLValue).getArgumentList().getExpressionArguments();
writeAssignmentWithSetter(((GrIndexProperty) realLValue).getInvokedExpression(), (PsiMethod) resolved, ArrayUtil.append(args, getRValue(expression)), GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, result.getSubstitutor(), expression);
return;
}
}
final PsiType lType = GenerationUtil.getDeclaredType(lValue, context);
if (token == GroovyTokenTypes.mASSIGN) {
//write simple assignment
lValue.accept(this);
builder.append(" = ");
if (rValue != null) {
final PsiType rType = GenerationUtil.getDeclaredType(rValue, context);
GenerationUtil.wrapInCastIfNeeded(builder, GenerationUtil.getNotNullType(expression, lType), rType, expression, context, new StatementWriter() {
@Override
public void writeStatement(StringBuilder builder, ExpressionContext context) {
rValue.accept(ExpressionGenerator.this);
}
});
}
} else {
//write assignment such as +=, -=, etc
final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(expression.multiResolve(false));
final PsiElement resolved = resolveResult.getElement();
if (resolved instanceof PsiMethod && !shouldNotReplaceOperatorWithMethod(lValue.getType(), rValue, expression.getOperationTokenType())) {
lValue.accept(this);
builder.append(" = ");
final PsiType rType = GenerationUtil.getDeclaredType((PsiMethod) resolved, resolveResult.getSubstitutor(), context);
GenerationUtil.wrapInCastIfNeeded(builder, GenerationUtil.getNotNullType(expression, lType), rType, expression, context, new StatementWriter() {
@Override
public void writeStatement(StringBuilder builder, ExpressionContext context) {
invokeMethodOn(((PsiMethod) resolved), (GrExpression) lValue.copy(), rValue == null ? GrExpression.EMPTY_ARRAY : new GrExpression[] { rValue }, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, resolveResult.getSubstitutor(), expression);
}
});
} else {
writeSimpleBinaryExpression(expression.getOperationToken(), lValue, rValue);
}
}
}
use of com.intellij.psi.tree.IElementType in project intellij-community by JetBrains.
the class ExpressionGenerator method visitBinaryExpression.
@Override
public void visitBinaryExpression(@NotNull GrBinaryExpression expression) {
final GrExpression left = expression.getLeftOperand();
GrExpression right = expression.getRightOperand();
final PsiType ltype = left.getType();
final PsiElement token = expression.getOperationToken();
final IElementType op = expression.getOperationTokenType();
if (op == GroovyTokenTypes.mREGEX_FIND) {
builder.append(GroovyCommonClassNames.JAVA_UTIL_REGEX_PATTERN).append(".compile(");
if (right != null) {
right.accept(this);
}
builder.append(").matcher(");
left.accept(this);
builder.append(')');
return;
}
if (op == GroovyTokenTypes.mREGEX_MATCH) {
builder.append(GroovyCommonClassNames.JAVA_UTIL_REGEX_PATTERN).append(".matches(");
if (right != null) {
right.accept(this);
}
builder.append(", ");
left.accept(this);
builder.append(')');
return;
}
if ((op == GroovyTokenTypes.mEQUAL || op == GroovyTokenTypes.mNOT_EQUAL) && (GrInspectionUtil.isNull(left) || right != null && GrInspectionUtil.isNull(right))) {
writeSimpleBinaryExpression(token, left, right);
return;
}
if (op == GroovyTokenTypes.kIN && right instanceof GrReferenceExpression && InheritanceUtil.isInheritor(right.getType(), CommonClassNames.JAVA_LANG_CLASS)) {
final PsiType type = com.intellij.psi.util.PsiUtil.substituteTypeParameter(right.getType(), CommonClassNames.JAVA_LANG_CLASS, 0, true);
writeInstanceof(left, type, expression);
return;
}
if (shouldNotReplaceOperatorWithMethod(ltype, right, op)) {
writeSimpleBinaryExpression(token, left, right);
return;
}
final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(expression.multiResolve(false));
final PsiElement resolved = resolveResult.getElement();
if (resolved instanceof PsiMethod) {
if (right == null) {
right = factory.createExpressionFromText("null");
}
if (op == GroovyTokenTypes.mNOT_EQUAL && "equals".equals(((PsiMethod) resolved).getName())) {
builder.append('!');
}
invokeMethodOn(((PsiMethod) resolved), left, new GrExpression[] { right }, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, resolveResult.getSubstitutor(), expression);
if (op == GroovyTokenTypes.mGE) {
builder.append(" >= 0");
} else if (op == GroovyTokenTypes.mGT) {
builder.append(" > 0");
} else if (op == GroovyTokenTypes.mLT) {
builder.append(" < 0");
} else if (op == GroovyTokenTypes.mLE)
builder.append(" <= 0");
} else {
writeSimpleBinaryExpression(token, left, right);
}
}
use of com.intellij.psi.tree.IElementType in project intellij-community by JetBrains.
the class ExpressionGenerator method getRValue.
/**
* returns rValue for lValue = expr
* lValue+Rvalue for lValue += rValue
*/
@Nullable
private GrExpression getRValue(GrAssignmentExpression expression) {
GrExpression rValue = expression.getRValue();
if (rValue == null)
return null;
GrExpression lValue = expression.getLValue();
IElementType opToken = expression.getOperationTokenType();
if (opToken == GroovyTokenTypes.mASSIGN)
return rValue;
Pair<String, IElementType> pair = GenerationUtil.getBinaryOperatorType(opToken);
LOG.assertTrue(pair != null);
return factory.createExpressionFromText(lValue.getText() + pair.getFirst() + rValue.getText(), expression);
}
Aggregations