/* * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jetbrains.plugins.groovy.lang.completion.handlers; import com.intellij.codeInsight.completion.InsertHandler; import com.intellij.codeInsight.completion.InsertionContext; import com.intellij.codeInsight.lookup.Lookup; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorModificationUtil; import com.intellij.openapi.editor.ScrollType; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.psi.javadoc.PsiDocTagValue; import com.intellij.psi.javadoc.PsiInlineDocTag; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.util.IncorrectOperationException; import com.intellij.util.text.CharArrayUtil; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocMemberReference; /** * @author Max Medvedev */ public class GroovyMethodSignatureInsertHandler implements InsertHandler<LookupElement> { private static final Logger LOG = Logger.getInstance(GroovyMethodSignatureInsertHandler.class); @Override public void handleInsert(InsertionContext context, LookupElement item) { if (!(item.getObject() instanceof PsiMethod)) { return; } PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getEditor().getDocument()); final Editor editor = context.getEditor(); final PsiMethod method = (PsiMethod)item.getObject(); final PsiParameter[] parameters = method.getParameterList().getParameters(); final StringBuilder buffer = new StringBuilder(); final CharSequence chars = editor.getDocument().getCharsSequence(); int endOffset = editor.getCaretModel().getOffset(); final Project project = context.getProject(); int afterSharp = CharArrayUtil.shiftBackwardUntil(chars, endOffset - 1, "#") + 1; int signatureOffset = afterSharp; PsiElement element = context.getFile().findElementAt(signatureOffset - 1); final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(element.getProject()); PsiDocTag tag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class); if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) { final PsiDocTagValue value = tag.getValueElement(); endOffset = value.getTextRange().getEndOffset(); } editor.getDocument().deleteString(afterSharp, endOffset); editor.getCaretModel().moveToOffset(signatureOffset); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); editor.getSelectionModel().removeSelection(); buffer.append(method.getName()).append("("); final int afterParenth = afterSharp + buffer.length(); for (int i = 0; i < parameters.length; i++) { final PsiType type = TypeConversionUtil.erasure(parameters[i].getType()); buffer.append(type.getCanonicalText()); if (i < parameters.length - 1) { buffer.append(","); if (styleSettings.SPACE_AFTER_COMMA) buffer.append(" "); } } buffer.append(")"); if (!(tag instanceof PsiInlineDocTag)) { buffer.append(" "); } else { final int currentOffset = editor.getCaretModel().getOffset(); if (chars.charAt(currentOffset) == '}') { afterSharp++; } else { buffer.append("} "); } } String insertString = buffer.toString(); EditorModificationUtil.insertStringAtCaret(editor, insertString); editor.getCaretModel().moveToOffset(afterSharp + buffer.length()); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); shortenReferences(project, editor, context, afterParenth); } private static void shortenReferences(final Project project, final Editor editor, InsertionContext context, int offset) { PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); final PsiElement element = context.getFile().findElementAt(offset); final GrDocMemberReference tagValue = PsiTreeUtil.getParentOfType(element, GrDocMemberReference.class); if (tagValue != null) { try { JavaCodeStyleManager.getInstance(project).shortenClassReferences(tagValue); } catch (IncorrectOperationException e) { LOG.error(e); } } PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments(); } }