Search in sources :

Example 1 with FormatFixer

use of com.intellij.lang.javascript.refactoring.FormatFixer in project intellij-plugins by JetBrains.

the class JSShortenFQNamesProcessor method processText.

public void processText(final Project project, final Template template, final Document document, final RangeMarker templateRange, final Editor editor) {
    if (!template.isToShortenLongNames())
        return;
    try {
        final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
        psiDocumentManager.commitDocument(document);
        final PsiFile hostFile = PsiUtilBase.getPsiFileInEditor(editor, project);
        final PsiFile file = (hostFile != null && JavaScriptSupportLoader.isFlexMxmFile(hostFile)) ? InjectedLanguageUtil.findInjectedPsiNoCommit(hostFile, templateRange.getStartOffset()) : hostFile;
        if (file instanceof JSFile && file.getLanguage().isKindOf(JavaScriptSupportLoader.ECMA_SCRIPT_L4)) {
            final ActionScriptUnusedImportsHelper.Results unusedImportsResults = ActionScriptUnusedImportsHelper.getUnusedImports(file);
            for (final JSReferenceExpression reference : unusedImportsResults.fqnsToReplaceWithShortName) {
                final TextRange range = InjectedLanguageManager.getInstance(project).injectedToHost(file, reference.getTextRange());
                if (TextRange.create(templateRange).contains(range)) {
                    final String shortName = StringUtil.getShortName(reference.getReferencedName());
                    final String resolved = JSImportHandlingUtil.resolveTypeName(shortName, reference);
                    // insert import statement if needed
                    if (shortName.equals(resolved)) {
                        final FormatFixer fixer = ImportUtils.insertImportStatements(reference, Collections.singletonList(reference.getText()));
                        if (fixer != null) {
                            fixer.fixFormat();
                        }
                    }
                    // shorten FQN
                    reference.replace(JSChangeUtil.createExpressionFromText(project, shortName).getPsi());
                }
            }
            psiDocumentManager.doPostponedOperationsAndUnblockDocument(document);
        }
    } catch (IncorrectOperationException e) {
        LOG.error(e);
    }
}
Also used : JSReferenceExpression(com.intellij.lang.javascript.psi.JSReferenceExpression) PsiFile(com.intellij.psi.PsiFile) TextRange(com.intellij.openapi.util.TextRange) IncorrectOperationException(com.intellij.util.IncorrectOperationException) ActionScriptUnusedImportsHelper(com.intellij.lang.javascript.validation.ActionScriptUnusedImportsHelper) JSFile(com.intellij.lang.javascript.psi.JSFile) FormatFixer(com.intellij.lang.javascript.refactoring.FormatFixer) PsiDocumentManager(com.intellij.psi.PsiDocumentManager)

Example 2 with FormatFixer

use of com.intellij.lang.javascript.refactoring.FormatFixer in project intellij-plugins by JetBrains.

the class ActionScriptCreateConstructorFix method applyFix.

@Override
protected void applyFix(final Project project, final PsiElement psiElement, PsiFile file, Editor editor) {
    final AtomicInteger count = new AtomicInteger();
    ReferencesSearch.search(myClass, myClass.getUseScope()).forEach(psiReference -> !isClassInstantiation(psiReference) || count.incrementAndGet() < 2);
    int usages = count.get();
    if (usages < 2) {
        usages += JSInheritanceUtil.findSuperConstructorCalls(myClass).size();
    }
    if (usages < 2) {
        final Collection<String> toImport = new ArrayList<>();
        for (JSExpression argument : myNode.getArguments()) {
            String type = JSResolveUtil.getQualifiedExpressionType(argument, argument.getContainingFile());
            if (StringUtil.isNotEmpty(type) && ImportUtils.needsImport(myClass, StringUtil.getPackageName(type))) {
                toImport.add(type);
            }
        }
        WriteAction.run(() -> {
            if (!toImport.isEmpty()) {
                FormatFixer formatFixer = ImportUtils.insertImportStatements(myClass, toImport);
                if (formatFixer != null) {
                    formatFixer.fixFormat();
                }
            }
            super.applyFix(project, psiElement, myClass.getContainingFile(), getEditor(myClass.getProject(), myClass.getContainingFile()));
        });
    } else {
        String text = "function " + myClass.getName() + "(){}";
        JSFunction fakeFunction = (JSFunction) JSChangeUtil.createStatementFromText(project, text, JavaScriptSupportLoader.ECMA_SCRIPT_L4).getPsi();
        new ChangeSignatureFix(fakeFunction, myNode.getArgumentList()) {

            @Override
            protected Pair<Boolean, List<JSParameterInfo>> handleCall(@NotNull JSFunction function, JSExpression[] arguments, boolean dummy) {
                List<JSParameterInfo> parameterInfos = super.handleCall(function, arguments, dummy).second;
                // always show dialog
                return Pair.create(true, parameterInfos);
            }

            @Override
            protected JSChangeSignatureDialog createDialog(PsiElement context, final List<JSParameterInfo> paramInfos) {
                JSMethodDescriptor descriptor = new JSMethodDescriptor(myFunction.getElement(), true) {

                    @Override
                    public List<JSParameterInfo> getParameters() {
                        return paramInfos;
                    }
                };
                return new MyDialog(descriptor, context);
            }

            @Override
            protected JSChangeSignatureProcessor createProcessor(List<JSParameterInfo> paramInfos, JSAttributeList attributeList, @NotNull JSFunction function) {
                return new MyProcessor(function, attributeList != null ? attributeList.getAccessType() : JSAttributeList.AccessType.PACKAGE_LOCAL, myClass.getName(), "", paramInfos.toArray(new JSParameterInfo[paramInfos.size()]), Collections.emptySet());
            }
        }.invoke(project, editor, file);
    }
}
Also used : JSAttributeList(com.intellij.lang.javascript.psi.ecmal4.JSAttributeList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) JSAttributeList(com.intellij.lang.javascript.psi.ecmal4.JSAttributeList) FormatFixer(com.intellij.lang.javascript.refactoring.FormatFixer) PsiElement(com.intellij.psi.PsiElement) Pair(com.intellij.openapi.util.Pair)

Example 3 with FormatFixer

use of com.intellij.lang.javascript.refactoring.FormatFixer in project intellij-plugins by JetBrains.

the class FlashUmlDataModel method createEdge.

@Override
@Nullable
public DiagramEdge<Object> createEdge(@NotNull final DiagramNode<Object> from, @NotNull final DiagramNode<Object> to) {
    final JSClass fromClass = (JSClass) from.getIdentifyingElement();
    final JSClass toClass = (JSClass) to.getIdentifyingElement();
    if (fromClass.isEquivalentTo(toClass)) {
        return null;
    }
    if (toClass.isInterface()) {
        if (JSPsiImplUtils.containsEquivalent(fromClass.isInterface() ? fromClass.getSuperClasses() : fromClass.getImplementedInterfaces(), toClass)) {
            return null;
        }
        Callable<DiagramEdge<Object>> callable = () -> {
            String targetQName = toClass.getQualifiedName();
            JSRefactoringUtil.addToSupersList(fromClass, targetQName, true);
            if (targetQName.contains(".") && !(fromClass instanceof XmlBackedJSClassImpl)) {
                List<FormatFixer> formatters = new ArrayList<>();
                formatters.add(ImportUtils.insertImportStatements(fromClass, Collections.singletonList(targetQName)));
                formatters.addAll(ECMAScriptImportOptimizer.executeNoFormat(fromClass.getContainingFile()));
                FormatFixer.fixAll(formatters);
            }
            return addEdgeAndRefresh(from, to, fromClass.isInterface() ? FlashUmlRelationship.GENERALIZATION : FlashUmlRelationship.INTERFACE_GENERALIZATION);
        };
        String commandName = FlexBundle.message(fromClass.isInterface() ? "create.extends.relationship.command.name" : "create.implements.relationship.command.name", fromClass.getQualifiedName(), toClass.getQualifiedName());
        return DiagramAction.performCommand(getBuilder(), callable, commandName, null, fromClass.getContainingFile());
    } else {
        if (fromClass.isInterface()) {
            return null;
        } else if (fromClass instanceof XmlBackedJSClassImpl) {
            JSClass[] superClasses = fromClass.getSuperClasses();
            if (JSPsiImplUtils.containsEquivalent(superClasses, toClass)) {
                return null;
            }
            if (superClasses.length > 0) {
                // if base component is not resolved, replace it silently
                final JSClass currentParent = superClasses[0];
                if (Messages.showYesNoDialog(FlexBundle.message("replace.base.component.prompt", currentParent.getQualifiedName(), toClass.getQualifiedName()), FlexBundle.message("create.edge.title"), Messages.getQuestionIcon()) == Messages.NO) {
                    return null;
                }
            }
            Callable<DiagramEdge<Object>> callable = () -> {
                NewFlexComponentAction.setParentComponent((MxmlJSClass) fromClass, toClass.getQualifiedName());
                return addEdgeAndRefresh(from, to, DiagramRelationships.GENERALIZATION);
            };
            String commandName = FlexBundle.message("create.extends.relationship.command.name", fromClass.getQualifiedName(), toClass.getQualifiedName());
            return DiagramAction.performCommand(getBuilder(), callable, commandName, null, fromClass.getContainingFile());
        } else {
            final JSClass[] superClasses = fromClass.getSuperClasses();
            if (JSPsiImplUtils.containsEquivalent(superClasses, toClass)) {
                return null;
            }
            if (superClasses.length > 0 && !JSResolveUtil.isObjectClass(superClasses[0])) {
                // if base class is not resolved, replace it silently
                final JSClass currentParent = superClasses[0];
                if (Messages.showYesNoDialog(FlexBundle.message("replace.base.class.prompt", currentParent.getQualifiedName(), toClass.getQualifiedName()), FlexBundle.message("create.edge.title"), Messages.getQuestionIcon()) == Messages.NO) {
                    return null;
                }
            }
            Callable<DiagramEdge<Object>> callable = () -> {
                List<FormatFixer> formatters = new ArrayList<>();
                boolean optimize = false;
                if (superClasses.length > 0 && !JSResolveUtil.isObjectClass(superClasses[0])) {
                    JSRefactoringUtil.removeFromReferenceList(fromClass.getExtendsList(), superClasses[0], formatters);
                    optimize = needsImport(fromClass, superClasses[0]);
                }
                JSRefactoringUtil.addToSupersList(fromClass, toClass.getQualifiedName(), false);
                if (needsImport(fromClass, toClass)) {
                    formatters.add(ImportUtils.insertImportStatements(fromClass, Collections.singletonList(toClass.getQualifiedName())));
                    optimize = true;
                }
                if (optimize) {
                    formatters.addAll(ECMAScriptImportOptimizer.executeNoFormat(fromClass.getContainingFile()));
                }
                FormatFixer.fixAll(formatters);
                return addEdgeAndRefresh(from, to, DiagramRelationships.GENERALIZATION);
            };
            String commandName = FlexBundle.message("create.extends.relationship.command.name", fromClass.getQualifiedName(), toClass.getQualifiedName());
            return DiagramAction.performCommand(getBuilder(), callable, commandName, null, fromClass.getContainingFile());
        }
    }
}
Also used : XmlBackedJSClassImpl(com.intellij.lang.javascript.flex.XmlBackedJSClassImpl) Callable(java.util.concurrent.Callable) JSReferenceList(com.intellij.lang.javascript.psi.ecmal4.JSReferenceList) MxmlJSClass(com.intellij.javascript.flex.mxml.MxmlJSClass) JSClass(com.intellij.lang.javascript.psi.ecmal4.JSClass) FormatFixer(com.intellij.lang.javascript.refactoring.FormatFixer) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with FormatFixer

use of com.intellij.lang.javascript.refactoring.FormatFixer in project intellij-plugins by JetBrains.

the class FlexMoveInnerClassProcessor method performRefactoring.

@Override
protected void performRefactoring(@NotNull UsageInfo[] usages) {
    try {
        ActionScriptCreateClassOrInterfaceFix.createClass(myClassName, myPackageName, myTargetDirectory, false);
    } catch (Exception e) {
        Messages.showErrorDialog(myProject, e.getMessage(), getCommandName());
        return;
    }
    final PsiFile sourceFile = myElement.getContainingFile();
    Collection<String> importsInTargetFile = new HashSet<>();
    Collection<String> namespacesInTargetFile = new HashSet<>();
    List<FormatFixer> formatters = new ArrayList<>();
    //JSRefactoringUtil.addRemovalFormatters(mySourceClass, myMembersToMove, Condition.TRUE, Condition.TRUE, postponedFormatters);
    JSClass targetClass = myElement instanceof JSClass ? (JSClass) myElement : null;
    JSRefactoringUtil.fixOutgoingReferences(myElement, importsInTargetFile, namespacesInTargetFile, Collections.singletonList(((JSAttributeListOwner) myElement)), targetClass, false, false);
    myElement.setName(myClassName);
    Collection<UsageInfo> usagesToProcess = new ArrayList<>(Arrays.asList(usages));
    for (Iterator<UsageInfo> i = usagesToProcess.iterator(); i.hasNext(); ) {
        UsageInfo usage = i.next();
        PsiElement element;
        if (usage instanceof NonCodeUsageInfo || (element = usage.getElement()) == null || !PsiTreeUtil.isAncestor(myElement, element, false)) {
            continue;
        }
        if (element instanceof JSReferenceExpression) {
            ((JSReferenceExpression) element).bindToElement(myElement);
        } else if (element instanceof PsiNamedElement) {
            ((PsiNamedElement) element).setName(myClassName);
        } else {
            continue;
        }
        i.remove();
    }
    final PsiElement clazz = ActionScriptClassResolver.findClassByQNameStatic(StringUtil.getQualifiedName(myPackageName, myClassName), GlobalSearchScope.projectScope(myProject));
    PsiElement toInsert = myElement instanceof JSVariable ? JSRefactoringUtil.getVarStatementCopy((JSVariable) myElement) : myElement.copy();
    final PsiElement inserted = clazz.replace(toInsert);
    PsiFile insertedContainingFile = inserted.getContainingFile();
    JSQualifiedNamedElement newClass = inserted instanceof JSVarStatement ? ((JSVarStatement) inserted).getVariables()[0] : (JSQualifiedNamedElement) inserted;
    SmartPsiElementPointer<JSQualifiedNamedElement> newClassPointer = SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(newClass);
    JSRefactoringUtil.handleDocCommentAndFormat(inserted, formatters);
    JSRefactoringUtil.deleteWithNoPostponedFormatting(myElement);
    if (myPackageName.length() > 0) {
        for (UsageInfo usage : usagesToProcess) {
            if (usage instanceof NonCodeUsageInfo || usage.getFile() != sourceFile)
                continue;
            final PsiElement element = usage.getElement();
            if (element == null)
                continue;
            ImportUtils.doImport(element, StringUtil.getQualifiedName(myPackageName, myClassName), true);
        }
    }
    JSRefactoringUtil.postProcess(sourceFile, newClass, Collections.singletonList(sourceFile), importsInTargetFile, namespacesInTargetFile, formatters, true, false);
    boolean makePublic = false;
    newClass = newClassPointer.getElement();
    List<NonCodeUsageInfo> nonCodeUsages = new ArrayList<>();
    for (UsageInfo usage : usagesToProcess) {
        if (usage instanceof NonCodeUsageInfo) {
            nonCodeUsages.add((NonCodeUsageInfo) usage);
        } else {
            JSReferenceExpression refExpr = (JSReferenceExpression) usage.getElement();
            if (refExpr == null) {
                continue;
            }
            makePublic |= JSPsiImplUtils.getQNameForMove(refExpr, newClass) != null;
            refExpr.bindToElement(newClass);
        }
    }
    JSChangeVisibilityUtil.setVisibility((JSAttributeListOwner) newClass, makePublic ? JSAttributeList.AccessType.PUBLIC : JSAttributeList.AccessType.PACKAGE_LOCAL);
    myNonCodeUsages = nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]);
    if (myMoveCallback != null) {
        myMoveCallback.refactoringCompleted();
    }
    OpenFileDescriptor descriptor = new OpenFileDescriptor(myProject, insertedContainingFile.getVirtualFile(), newClass.getTextOffset());
    FileEditorManager.getInstance(myProject).openTextEditor(descriptor, true);
}
Also used : NonCodeUsageInfo(com.intellij.refactoring.util.NonCodeUsageInfo) JSQualifiedNamedElement(com.intellij.lang.javascript.psi.ecmal4.JSQualifiedNamedElement) JSVariable(com.intellij.lang.javascript.psi.JSVariable) JSReferenceExpression(com.intellij.lang.javascript.psi.JSReferenceExpression) OpenFileDescriptor(com.intellij.openapi.fileEditor.OpenFileDescriptor) JSVarStatement(com.intellij.lang.javascript.psi.JSVarStatement) JSClass(com.intellij.lang.javascript.psi.ecmal4.JSClass) FormatFixer(com.intellij.lang.javascript.refactoring.FormatFixer) NonCodeUsageInfo(com.intellij.refactoring.util.NonCodeUsageInfo)

Aggregations

FormatFixer (com.intellij.lang.javascript.refactoring.FormatFixer)4 JSReferenceExpression (com.intellij.lang.javascript.psi.JSReferenceExpression)2 JSClass (com.intellij.lang.javascript.psi.ecmal4.JSClass)2 MxmlJSClass (com.intellij.javascript.flex.mxml.MxmlJSClass)1 XmlBackedJSClassImpl (com.intellij.lang.javascript.flex.XmlBackedJSClassImpl)1 JSFile (com.intellij.lang.javascript.psi.JSFile)1 JSVarStatement (com.intellij.lang.javascript.psi.JSVarStatement)1 JSVariable (com.intellij.lang.javascript.psi.JSVariable)1 JSAttributeList (com.intellij.lang.javascript.psi.ecmal4.JSAttributeList)1 JSQualifiedNamedElement (com.intellij.lang.javascript.psi.ecmal4.JSQualifiedNamedElement)1 JSReferenceList (com.intellij.lang.javascript.psi.ecmal4.JSReferenceList)1 ActionScriptUnusedImportsHelper (com.intellij.lang.javascript.validation.ActionScriptUnusedImportsHelper)1 OpenFileDescriptor (com.intellij.openapi.fileEditor.OpenFileDescriptor)1 Pair (com.intellij.openapi.util.Pair)1 TextRange (com.intellij.openapi.util.TextRange)1 PsiDocumentManager (com.intellij.psi.PsiDocumentManager)1 PsiElement (com.intellij.psi.PsiElement)1 PsiFile (com.intellij.psi.PsiFile)1 NonCodeUsageInfo (com.intellij.refactoring.util.NonCodeUsageInfo)1 IncorrectOperationException (com.intellij.util.IncorrectOperationException)1