private static void setupFunctionResult(@NotNull Template template, @Nullable GoType type) { if (type instanceof GoTypeList) { template.addTextSegment(" ("); List<GoType> list = ((GoTypeList)type).getTypeList(); for (int i = 0; i < list.size(); i++) { template.addVariable(new ConstantNode(list.get(i).getText()), true); if (i < list.size() - 1) template.addTextSegment(", "); } template.addTextSegment(")"); return; } if (type != null) { template.addTextSegment(" "); template.addVariable(new ConstantNode(type.getText()), true); } }
@Override public void invoke(@NotNull Project project, @NotNull PsiFile file, @Nullable("is null when called from inspection") Editor editor, @NotNull PsiElement startElement, @NotNull PsiElement endElement) { if (!(file instanceof GoFile) || editor == null || !(startElement instanceof GoBlock)) return; PsiElement brace = ((GoBlock)startElement).getRbrace(); if (brace == null) return; Template template = TemplateSettings.getInstance().getTemplateById("go_lang_add_return"); if (template == null) return; int start = brace.getTextRange().getStartOffset(); editor.getCaretModel().moveToOffset(start); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); template.setToReformat(true); TemplateManager.getInstance(project).startTemplate(editor, template, true, Collections.emptyMap(), null); } }
@Nullable @Override public Result calculateResult(@NotNull Expression[] params, ExpressionContext context) { String name = ContainerUtil.getFirstItem(fieldNames(context)); return StringUtil.isNotEmpty(name) ? new TextResult(name) : null; }
@Override public void invoke(@NotNull Project project, @NotNull PsiFile file, @Nullable("is null when called from inspection") Editor editor, @NotNull PsiElement startElement, @NotNull PsiElement endElement) { if (editor == null) { LOG.error("Cannot run quick fix without editor: " + getClass().getSimpleName(), AttachmentFactory.createAttachment(file.getVirtualFile())); return; } if (!(startElement instanceof GoType)) return; GoType type = (GoType)startElement; PsiElement anchor = PsiTreeUtil.findPrevParent(file, type); String name = "TypeName"; GoTypeDeclaration decl = (GoTypeDeclaration)file.addBefore(GoElementFactory.createTypeDeclaration(project, name, type), anchor); if (decl == null) return; decl = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(decl); if (decl == null) return; GoTypeSpec spec = ContainerUtil.getFirstItem(decl.getTypeSpecList()); if (spec == null) return; TemplateBuilderImpl builder = new TemplateBuilderImpl(file); builder.replaceElement(type, OTHER_NAME, INPUT_NAME, false); builder.replaceElement(spec.getIdentifier(), INPUT_NAME, new ConstantNode(name), true); editor.getCaretModel().moveToOffset(file.getTextRange().getStartOffset()); Template template = builder.buildInlineTemplate(); editor.getCaretModel().moveToOffset(file.getTextRange().getStartOffset()); TemplateManager.getInstance(project).startTemplate(editor, template); }
@Override public void handleInsert(@NotNull InsertionContext context, LookupElement item) { Editor editor = context.getEditor(); CharSequence documentText = context.getDocument().getImmutableCharSequence(); int offset = skipWhiteSpaces(editor.getCaretModel().getOffset(), documentText); if (documentText.charAt(offset) != '{') { Project project = context.getProject(); Template template = TemplateManager.getInstance(project).createTemplate("braces", "go", myOneLine ? "{$END$}" : " {\n$END$\n}"); template.setToReformat(true); TemplateManager.getInstance(project).startTemplate(editor, template); } else { editor.getCaretModel().moveToOffset(offset); ApplicationManager.getApplication().runWriteAction(() -> { EditorActionHandler enterAction = EditorActionManager.getInstance().getActionHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE); enterAction.execute(editor, editor.getCaretModel().getCurrentCaret(), ((EditorEx)editor).getDataContext()); }); } }
@Override public void invoke(@NotNull Project project, @NotNull PsiFile file, @Nullable("is null when called from inspection") Editor editor, @NotNull PsiElement startElement, @NotNull PsiElement endElement) { if (editor == null) { LOG.error("Cannot run quick fix without editor: " + getClass().getSimpleName(), AttachmentFactory.createAttachment(file.getVirtualFile())); return; } if (!(startElement instanceof GoCallExpr)) return; GoCallExpr call = (GoCallExpr)startElement; List<GoExpression> args = call.getArgumentList().getExpressionList(); GoType resultType = ContainerUtil.getFirstItem(GoTypeUtil.getExpectedTypes(call)); PsiElement anchor = PsiTreeUtil.findPrevParent(file, call); Template template = TemplateManager.getInstance(project).createTemplate("", ""); template.addTextSegment("\nfunc " + myName); setupFunctionParameters(template, args, file); setupFunctionResult(template, resultType); template.addTextSegment(" {\n\t"); template.addEndVariable(); template.addTextSegment("\n}"); int offset = anchor.getTextRange().getEndOffset(); editor.getCaretModel().moveToOffset(offset); startTemplate(editor, template, project); }
@Override public void setVariables(@NotNull Template template, @NotNull PsiElement element) { MacroCallNode node = new MacroCallNode(new IterableComponentTypeMacro()); MacroCallNode name = new MacroCallNode(new SuggestVariableNameMacro()); node.addParameter(new VariableNode("expr", null)); template.addVariable("name" + i, name, name, true); template.addVariable("value" + i, name, name, true); template.addVariable("name" + i, name, name, true); template.addVariable("value" + i, name, name, true); template.addVariable("name" + i, name, name, true); template.addVariable("value" + i, name, name, true); template.addVariable("name" + size, name, name, true); template.addVariable("value" + size, name, name, true);
private static void startTemplate(@NotNull Editor editor, @NotNull Template template, @NotNull Project project) { Runnable runnable = () -> { if (project.isDisposed() || editor.isDisposed()) return; CommandProcessor.getInstance().executeCommand(project, () -> TemplateManager.getInstance(project).startTemplate(editor, template, null), "Introduce function", null); }; if (ApplicationManager.getApplication().isUnitTestMode()) { runnable.run(); } else { ApplicationManager.getApplication().invokeLater(runnable); } }
@NotNull @Override public LookupElement[] calculateLookupItems(ExpressionContext context) { int offset = context.getStartOffset(); Project project = context.getProject(); PsiDocumentManager.getInstance(project).commitAllDocuments(); assert context.getEditor() != null; PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(context.getEditor().getDocument()); assert file != null; PsiElement elementAt = file.findElementAt(offset); Set<String> parameterNames = ContainerUtil.newHashSet(); GoParameters parameters = PsiTreeUtil.getParentOfType(elementAt, GoParameters.class); if (parameters != null) { GoParamDefinition parameter = PsiTreeUtil.getParentOfType(elementAt, GoParamDefinition.class); for (GoParameterDeclaration paramDecl : parameters.getParameterDeclarationList()) { for (GoParamDefinition paramDef : paramDecl.getParamDefinitionList()) { if (parameter != paramDef) { parameterNames.add(paramDef.getName()); } } } } Set<LookupElement> set = ContainerUtil.newLinkedHashSet(); for (String name : myNames) { set.add(LookupElementBuilder.create(UniqueNameGenerator.generateUniqueName(name, parameterNames))); } return set.toArray(new LookupElement[set.size()]); } }
private static Set<String> fieldNames(ExpressionContext context) { PsiElement psiElement = context != null ? context.getPsiElementAtStartOffset() : null; GoFieldDeclaration fieldDeclaration = PsiTreeUtil.getNonStrictParentOfType(psiElement, GoFieldDeclaration.class); if (fieldDeclaration == null) { return Collections.emptySet(); } return ContainerUtil.map2LinkedSet(fieldDeclaration.getFieldDefinitionList(), PsiNamedElement::getName); } }
@Override public boolean isInContext(@NotNull PsiFile file, int offset) { return isMyLanguage(PsiUtilCore.getLanguageAtOffset(file, offset)) && !XmlContextType.isEmbeddedContent(file, offset) && isMyFile(file); }
@Nullable public static InsertHandler<LookupElement> createTemplateBasedInsertHandler(@NotNull String templateId) { return (context, item) -> { Template template = TemplateSettings.getInstance().getTemplateById(templateId); Editor editor = context.getEditor(); if (template != null) { editor.getDocument().deleteString(context.getStartOffset(), context.getTailOffset()); TemplateManager.getInstance(context.getProject()).startTemplate(editor, template); } else { int currentOffset = editor.getCaretModel().getOffset(); CharSequence documentText = editor.getDocument().getImmutableCharSequence(); if (documentText.length() <= currentOffset || documentText.charAt(currentOffset) != ' ') { EditorModificationUtil.insertStringAtCaret(editor, " "); } else { EditorModificationUtil.moveCaretRelatively(editor, 1); } } }; } }
private static void setupFunctionParameters(@NotNull Template template, @NotNull List<GoExpression> args, PsiFile file) { Map<String, GoImportSpec> importMap = ((GoFile)file).getImportedPackagesMap(); template.addTextSegment("("); for (int i = 0; i < args.size(); i++) { GoExpression e = args.get(i); template.addVariable(GoRefactoringUtil.createParameterNameSuggestedExpression(e), true); template.addTextSegment(" "); String type = convertType(file, e.getGoType(null), importMap); template.addVariable(new ConstantNode(type), true); if (i != args.size() - 1) template.addTextSegment(", "); } template.addTextSegment(")"); }
@Nullable @Override public Result calculateResult(ExpressionContext context) { LookupElement firstElement = ArrayUtil.getFirstElement(calculateLookupItems(context)); return new TextResult(firstElement != null ? firstElement.getLookupString() : ""); }
@Override public void invoke(@NotNull Project project, @NotNull PsiFile file, @Nullable("is null when called from inspection") Editor editor, @NotNull PsiElement startElement, @NotNull PsiElement endElement) { if (editor == null) { LOG.error("Cannot run quick fix without editor: " + getClass().getSimpleName(), AttachmentFactory.createAttachment(file.getVirtualFile())); return; } PsiElement reference = PsiTreeUtil.getNonStrictParentOfType(startElement, GoReferenceExpressionBase.class); PsiElement anchor = reference != null ? findAnchor(reference) : null; if (anchor == null) { LOG.error("Cannot find anchor for " + myWhat + " (GoUnresolvedFixBase), offset: " + editor.getCaretModel().getOffset(), AttachmentFactory.createAttachment(file.getVirtualFile())); return; } Template template = TemplateSettings.getInstance().getTemplateById(myTemplateId); if (template == null) { LOG.error("Cannot find anchor for " + myWhat + " (GoUnresolvedFixBase), offset: " + editor.getCaretModel().getOffset(), AttachmentFactory.createAttachment(file.getVirtualFile())); return; } int start = anchor.getTextRange().getStartOffset(); editor.getCaretModel().moveToOffset(start); template.setToReformat(true); TemplateManager.getInstance(project).startTemplate(editor, template, true, ContainerUtil.stringMap("NAME", myName), null); }
@Nullable @Override protected Result getResultByTokenType(Project project, IElementType tokenType) { if (tokenType == TT2_OUTLINE_TAG) { return new TextResult(""); } else if (tokenType == TT2_OPEN_TAG) { return new TextResult(TemplateToolkitSettings.getInstance(project).END_TAG); } return null; } }
@NotNull private static InsertHandler<LookupElement> createTemplateBasedInsertHandler(@NotNull String templateId, @Nullable String traileringString) { return (context, item) -> { Template template = TemplateSettings.getInstance().getTemplateById(templateId); Editor editor = context.getEditor(); if (template != null) { editor.getDocument().deleteString(context.getStartOffset(), context.getTailOffset()); TemplateManager.getInstance(context.getProject()).startTemplate(editor, template); } else { int currentOffset = editor.getCaretModel().getOffset(); CharSequence documentText = editor.getDocument().getImmutableCharSequence(); if (documentText.length() <= currentOffset || documentText.charAt(currentOffset) != ' ') { if (traileringString != null) { EditorModificationUtil.insertStringAtCaret(editor, traileringString); } } else { EditorModificationUtil.moveCaretRelatively(editor, 1); } } }; }
@NotNull @Override public Result calculateQuickResult(ExpressionContext context) { return new TextResult(child.getText()); }
@NotNull @Override public Result calculateResult(ExpressionContext context) { return new TextResult(child.getText()); }
@Nullable protected Result getResultByTokenType(Project project, IElementType tokenType) { if (tokenType == TT2_OUTLINE_TAG) { return new TextResult(TemplateToolkitSettings.getInstance(project).OUTLINE_TAG); } else if (tokenType == TT2_OPEN_TAG) { return new TextResult(TemplateToolkitSettings.getInstance(project).START_TAG); } return null; }