@Nullable private static PsiType guessElementTypeFromReference( MethodPatternMap methodPatternMap, PsiElement ref, TextRange rangeToIgnore) { PsiElement refParent = ref.getParent(); if (refParent instanceof PsiReferenceExpression) { PsiReferenceExpression parentExpr = (PsiReferenceExpression) refParent; if (ref.equals(parentExpr.getQualifierExpression()) && parentExpr.getParent() instanceof PsiMethodCallExpression) { String methodName = parentExpr.getReferenceName(); PsiMethodCallExpression methodCall = (PsiMethodCallExpression) parentExpr.getParent(); PsiExpression[] args = methodCall.getArgumentList().getExpressions(); MethodPattern pattern = methodPatternMap.findPattern(methodName, args.length); if (pattern != null) { if (pattern.parameterIndex < 0) { // return value if (methodCall.getParent() instanceof PsiTypeCastExpression && (rangeToIgnore == null || !rangeToIgnore.contains(methodCall.getTextRange()))) { return ((PsiTypeCastExpression) methodCall.getParent()).getType(); } } else { return args[pattern.parameterIndex].getType(); } } } } return null; }
@Override protected void invokeImpl(PsiClass targetClass) { final PsiFile callSite = myMethodCall.getContainingFile(); final Project project = myMethodCall.getProject(); PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace(); try { PsiMethod constructor = elementFactory.createConstructor(); constructor = (PsiMethod) targetClass.add(constructor); final TemplateBuilderImpl templateBuilder = new TemplateBuilderImpl(constructor); CreateFromUsageUtils.setupMethodParameters( constructor, templateBuilder, myMethodCall.getArgumentList(), getTargetSubstitutor(myMethodCall)); final PsiFile psiFile = myMethodCall.getContainingFile(); templateBuilder.setEndVariableAfter(constructor.getBody().getLBrace()); final RangeMarker rangeMarker = psiFile.getViewProvider().getDocument().createRangeMarker(myMethodCall.getTextRange()); constructor = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(constructor); targetClass = constructor.getContainingClass(); myMethodCall = CodeInsightUtil.findElementInRange( psiFile, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), myMethodCall.getClass()); rangeMarker.dispose(); Template template = templateBuilder.buildTemplate(); final Editor editor = positionCursor(project, targetClass.getContainingFile(), targetClass); if (editor == null) return; final TextRange textRange = constructor.getTextRange(); final PsiFile file = targetClass.getContainingFile(); editor.getDocument().deleteString(textRange.getStartOffset(), textRange.getEndOffset()); editor.getCaretModel().moveToOffset(textRange.getStartOffset()); startTemplate( editor, template, project, new TemplateEditingAdapter() { @Override public void templateFinished(Template template, boolean brokenOff) { ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { try { PsiDocumentManager.getInstance(project) .commitDocument(editor.getDocument()); final int offset = editor.getCaretModel().getOffset(); PsiMethod constructor = PsiTreeUtil.findElementOfClassAtOffset( file, offset, PsiMethod.class, false); CreateFromUsageUtils.setupMethodBody(constructor); CreateFromUsageUtils.setupEditor(constructor, editor); UndoUtil.markPsiFileForUndo(callSite); } catch (IncorrectOperationException e) { LOG.error(e); } } }); } }); } catch (IncorrectOperationException e) { LOG.error(e); } }