void (@NotNull PyTargetExpression target, @NotNull TypeEvalContext context, @NotNull AnnotationInfo info, boolean startTemplate) { final LanguageLevel langLevel = LanguageLevel.forElement(target); if (langLevel.isOlderThan(LanguageLevel.PYTHON36)) { throw new IllegalArgumentException("Target '" + target.getText() + "' doesn't belong to Python 3.6+ project: " + langLevel); } final PyClass pyClass = target.getContainingClass(); if (pyClass == null) { throw new IllegalArgumentException("Target '" + target.getText() + "' in not contained in a class definition"); } if (!FileModificationService.getInstance().preparePsiElementForWrite(target)) return; final PyElementGenerator generator = PyElementGenerator.getInstance(target.getProject()); final String declarationText = target.getName() + ": " + info.getAnnotationText(); final PyTypeDeclarationStatement declaration = generator.createFromText(langLevel, PyTypeDeclarationStatement.class, declarationText); final PsiElement anchorBefore = findPrecedingAnchorForAttributeDeclaration(pyClass); WriteAction.run(() -> { PyTypeDeclarationStatement inserted = (PyTypeDeclarationStatement)pyClass.getStatementList().addAfter(declaration, anchorBefore); addImportsForTypeAnnotations(info.getTypes(), context, target.getContainingFile()); inserted = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(inserted); if (startTemplate && inserted != null) { openEditorAndAddTemplateForAnnotation(inserted); } }); }