下面列出了怎么用com.intellij.psi.PsiExpression的API类实例代码及写法,或者点击链接到github查看源代码。
@VisibleForTesting
static PsiExpression createMethodChain(
Project project, String firstName, List<? extends String> methodNames) {
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
StringBuilder expressionText =
new StringBuilder(firstName + "(" + TEMPLATE_INSERT_PLACEHOLDER_C + ")");
methodNames.forEach(
methodName ->
expressionText
.append("\n.")
.append(methodName)
.append("(")
.append(TEMPLATE_INSERT_PLACEHOLDER)
.append(")"));
return factory.createExpressionFromText(expressionText.toString(), null);
}
@Test
public void createMethodChain() {
testHelper.runInReadAction(
project -> {
List<String> names = new ArrayList<>(2);
names.add("methodName1");
names.add("otherName");
PsiExpression methodChain =
MethodChainLookupElement.createMethodChain(project, "methodNameBase", names);
assertEquals(
"methodNameBase(insert_placeholder_c)\n"
+ ".methodName1(insert_placeholder)\n"
+ ".otherName(insert_placeholder)",
methodChain.getText());
});
}
private void visitPsiFields(final PsiField psiField) {
if (!ClassUtils.isPrimitive(psiField.getType())) {
String type = removeSpecialSymbols(psiField.getType().getCanonicalText());
if (psiField.getInitializer() != null) {
PsiExpression psiExpression = psiField.getInitializer();
if (psiExpression != null) {
PsiType psiType = psiExpression.getType();
if (psiType != null && !ClassUtils.isPrimitive(psiType)) {
String psiFieldInitializer =
removeSpecialSymbols(psiType.getCanonicalText());
addInMap(psiFieldInitializer, emptySet);
}
}
}
addInMap(type, emptySet);
}
}
@Override
public IntroduceVariableSettings getSettings(Project project, Editor editor, PsiExpression expr,
PsiExpression[] occurrences, TypeSelectorManagerImpl typeSelectorManager,
boolean declareFinalIfAll, boolean anyAssignmentLHS, InputValidator validator,
PsiElement anchor, JavaReplaceChoice replaceChoice) {
final IntroduceVariableSettings variableSettings;
if (ApplicationManager.getApplication().isUnitTestMode()) {
variableSettings = new UnitTestMockVariableSettings(expr);
} else {
variableSettings = super.getSettings(project, editor, expr, occurrences, typeSelectorManager, declareFinalIfAll,
anyAssignmentLHS, validator, anchor, replaceChoice);
}
return getIntroduceVariableSettings(project, variableSettings);
}
private void processExpression(PsiExpression expression) {
ExpressionExtractor expressionExtractor = new ExpressionExtractor();
List<PsiExpression> assignments = expressionExtractor.getAssignments(expression);
List<PsiExpression> postfixExpressions = expressionExtractor.getPostfixExpressions(expression);
List<PsiExpression> prefixExpressions = expressionExtractor.getPrefixExpressions(expression);
processVariables(expressionExtractor.getVariableInstructions(expression), assignments, postfixExpressions, prefixExpressions);
processMethodInvocations(expressionExtractor.getMethodInvocations(expression));
processClassInstanceCreations(expressionExtractor.getClassInstanceCreations(expression));
processArrayCreations(expressionExtractor.getArrayCreations(expression));
processLiterals(expressionExtractor.getLiterals(expression));
}
public String toString() {
PsiExpression expression = getExpression();
if (expression == null || expression.getType() == null) {
return "";
} else {
return expression.getType().getCanonicalText();
}
}
private static void handleIfMethodCall(
@Nullable PsiExpression expression,
BiConsumer<Collection<String>, PsiReferenceExpression> errorHandler,
Function<PsiMethodCallExpression, PsiClass> generatedClassResolver) {
if (expression instanceof PsiMethodCallExpression) {
PsiMethodCallExpression rootMethodCall = (PsiMethodCallExpression) expression;
handleMethodCall(rootMethodCall, new HashSet<>(), errorHandler, generatedClassResolver);
}
}
private static void handleMethodCall(
PsiMethodCallExpression currentMethodCall,
Set<String> methodNamesCalled,
BiConsumer<Collection<String>, PsiReferenceExpression> errorHandler,
Function<PsiMethodCallExpression, PsiClass> generatedClassResolver) {
PsiReferenceExpression methodExpression = currentMethodCall.getMethodExpression();
methodNamesCalled.add(methodExpression.getReferenceName());
// Assumption to find next method in a call chain
PsiMethodCallExpression nextMethodCall =
PsiTreeUtil.getChildOfType(methodExpression, PsiMethodCallExpression.class);
if (nextMethodCall != null) {
handleMethodCall(nextMethodCall, methodNamesCalled, errorHandler, generatedClassResolver);
} else if ("create".equals(methodExpression.getReferenceName())) {
// Finish call chain
// TODO T47712852: allow setting required prop in another statement
Optional.ofNullable(generatedClassResolver.apply(currentMethodCall))
.map(generatedCls -> collectMissingRequiredProps(generatedCls, methodNamesCalled))
.filter(result -> !result.isEmpty())
.ifPresent(
missingRequiredProps -> errorHandler.accept(missingRequiredProps, methodExpression));
}
PsiExpressionList argumentList = currentMethodCall.getArgumentList();
for (PsiExpression argument : argumentList.getExpressions()) {
handleIfMethodCall(argument, errorHandler, generatedClassResolver);
}
}
@Nullable
@Override
public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
if (ServiceManager.getService(element.getProject(), CamelService.class).isCamelPresent()) {
PsiExpressionList exps = PsiTreeUtil.getNextSiblingOfType(originalElement, PsiExpressionList.class);
if (exps != null) {
if (exps.getExpressions().length >= 1) {
// grab first string parameter (as the string would contain the camel endpoint uri
final PsiClassType stringType = PsiType.getJavaLangString(element.getManager(), element.getResolveScope());
PsiExpression exp = Arrays.stream(exps.getExpressions()).filter(
e -> e.getType() != null && stringType.isAssignableFrom(e.getType()))
.findFirst().orElse(null);
if (exp instanceof PsiLiteralExpression) {
Object o = ((PsiLiteralExpression) exp).getValue();
String val = o != null ? o.toString() : null;
// okay only allow this popup to work when its from a RouteBuilder class
PsiClass clazz = PsiTreeUtil.getParentOfType(originalElement, PsiClass.class);
if (clazz != null) {
PsiClassType[] types = clazz.getExtendsListTypes();
boolean found = Arrays.stream(types).anyMatch(p -> p.getClassName().equals("RouteBuilder"));
if (found) {
String componentName = asComponentName(val);
if (componentName != null) {
// the quick info cannot be so wide so wrap at 120 chars
return generateCamelComponentDocumentation(componentName, val, 120, element.getProject());
}
}
}
}
}
}
}
return null;
}
/**
* Returns the first operand from a {@link PsiPolyadicExpression}
*
* @param psiLiteralExpression the {@link PsiLiteralExpression} that is part of a {@link PsiPolyadicExpression}
* @return the first {@link PsiExpression} if the given {@link PsiLiteralExpression} is part of a {@link PsiPolyadicExpression}, null otherwise
*/
@Nullable
private static PsiExpression getFirstExpressionFromPolyadicExpression(PsiLiteralExpression psiLiteralExpression) {
if (isPartOfPolyadicExpression(psiLiteralExpression)) {
PsiPolyadicExpression psiPolyadicExpression = PsiTreeUtil.getParentOfType(psiLiteralExpression, PsiPolyadicExpression.class);
if (psiPolyadicExpression != null) {
return psiPolyadicExpression.getOperands()[0];
}
}
return null;
}
private void visitPsiReferenceExpression(final PsiReferenceExpression element) {
PsiExpression psiExpression = element.getQualifierExpression();
if (psiExpression != null) {
PsiType psiType = psiExpression.getType();
if (psiType != null) {
String qualifiedName = removeSpecialSymbols(psiType.getCanonicalText());
addInMap(qualifiedName, emptySet);
}
}
}
private void visitPsiReturnStatement(final PsiReturnStatement element) {
PsiExpression returnValue = element.getReturnValue();
if (returnValue != null) {
PsiType returnType = returnValue.getType();
if (returnType != null) {
String qualifiedName = removeSpecialSymbols(returnType.getCanonicalText());
addInMap(qualifiedName, emptySet);
}
}
}
public static void translate(PsiExpressionList element, TranslationContext ctx) {
PsiExpression[] arguments = element.getExpressions();
for (int i = 0; i < arguments.length; i++) {
ExpressionTranslator.translate(arguments[i], ctx);
if (i != arguments.length - 1) {
ctx.append(", ");
}
}
}
public static void translate(PsiPolyadicExpression element, TranslationContext ctx) {
for (PsiExpression expression : element.getOperands()) {
PsiJavaToken token = element.getTokenBeforeOperand(expression);
if (token != null) {
ctx.append(' ');
JavaTokenTranslator.translate(token, ctx);
ctx.append(' ');
}
ExpressionTranslator.translate(expression, ctx);
}
}
@Override
public void invoke(@NotNull Project project, @NotNull PsiFile psiFile, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
final PsiClass myClass = (PsiClass) startElement;
final Editor editor = CodeInsightUtil.positionCursor(project, psiFile, myClass.getLBrace());
if (editor != null) {
WriteCommandAction.writeCommandAction(project, psiFile).run(() ->
{
final PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(project);
final PsiField psiField = psiElementFactory.createField(myName, myType);
final PsiModifierList modifierList = psiField.getModifierList();
if (null != modifierList) {
for (String modifier : myModifiers) {
modifierList.setModifierProperty(modifier, true);
}
}
if (null != myInitializerText) {
PsiExpression psiInitializer = psiElementFactory.createExpressionFromText(myInitializerText, psiField);
psiField.setInitializer(psiInitializer);
}
final List<PsiGenerationInfo<PsiField>> generationInfos = GenerateMembersUtil.insertMembersAtOffset(myClass.getContainingFile(), editor.getCaretModel().getOffset(),
Collections.singletonList(new PsiGenerationInfo<>(psiField)));
if (!generationInfos.isEmpty()) {
PsiField psiMember = generationInfos.iterator().next().getPsiMember();
editor.getCaretModel().moveToOffset(psiMember.getTextRange().getEndOffset());
}
UndoUtil.markPsiFileForUndo(psiFile);
}
);
}
}
public List<PsiExpression> getLiterals() {
if (methodBody != null)
return methodBody.getLiterals();
else
return new ArrayList<>();
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiPostfixExpression;
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiBinaryExpression;
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiPrefixExpression;
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiSuperExpression;
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiTypeCastExpression;
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiNewExpression;
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiSuperExpression;
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiAssignmentExpression;
}
public boolean instanceOf(PsiExpression expression) {
return (expression instanceof PsiReferenceExpression &&
((PsiReferenceExpression) expression).resolve() instanceof PsiVariable);
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiNewExpression;
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiThisExpression;
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiLiteralExpression;
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiArrayAccessExpression;
}
public boolean instanceOf(PsiExpression expression) {
return expression instanceof PsiMethodCallExpression;
}