Search in sources :

Example 71 with PsiDocumentManager

use of com.intellij.psi.PsiDocumentManager in project android by JetBrains.

the class ResourceFolderRepositoryTest method testGradualEdits.

public void testGradualEdits() throws Exception {
    resetScanCounter();
    // Gradually type in the contents of a value file and make sure we end up with a valid view of the world
    VirtualFile file1 = myFixture.copyFileToProject(VALUES_EMPTY, "res/values/myvalues.xml");
    PsiFile psiFile1 = PsiManager.getInstance(getProject()).findFile(file1);
    assertNotNull(psiFile1);
    final ResourceFolderRepository resources = createRepository();
    assertNotNull(resources);
    final long generation = resources.getModificationCount();
    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
    final Document document = documentManager.getDocument(psiFile1);
    assertNotNull(document);
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            document.deleteString(0, document.getTextLength());
            documentManager.commitDocument(document);
        }
    });
    final String contents = "<!--\n" + "  -->\n" + "\n" + "<resources xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n" + "\n" + "    <!-- Titles -->\n" + "    <string name=\"app_name\">Animations Demo</string>\n" + "    <string name=\"title_zoom\">Zoom</string>\n" + "    <string name=\"title_layout_changes\">Layout Changes</string>\n" + "    <string name=\"title_template_step\">Step <xliff:g id=\"step_number\">%1$d</xliff:g>: Lorem\n" + "        Ipsum</string>\n" + "    <string name=\"ellipsis\">Here it is: \\u2026!</string>\n" + "\n" + "    <item type=\"id\" name=\"action_next\" />\n" + "\n" + "    <style name=\"DarkActionBar\" parent=\"android:Widget.Holo.ActionBar\">\n" + "        <item name=\"android:background\">@android:color/transparent</item>\n" + "    </style>\n" + "\n" + "    <integer name=\"card_flip_time_half\">150</integer>\n" + "\n" + "    <declare-styleable name=\"MyCustomView\">\n" + "        <attr name=\"watchType\" format=\"enum\">\n" + "            <enum name=\"type_countdown\" value=\"0\"/>\n" + "        </attr>\n" + "       <attr name=\"crash\" format=\"boolean\" />\n" + "    </declare-styleable>\n" + "</resources>\n";
    for (int i = 0; i < contents.length(); i++) {
        final int offset = i;
        final char character = contents.charAt(i);
        WriteCommandAction.runWriteCommandAction(null, new Runnable() {

            @Override
            public void run() {
                document.insertString(offset, String.valueOf(character));
                documentManager.commitDocument(document);
            }
        });
    }
    assertTrue(resources.isScanPending(psiFile1));
    UIUtil.dispatchAllInvocationEvents();
    UIUtil.invokeAndWaitIfNeeded(new Runnable() {

        @Override
        public void run() {
            ensureSingleScan();
            assertTrue(generation < resources.getModificationCount());
            assertTrue(resources.hasResourceItem(ResourceType.STYLE, "DarkActionBar"));
            assertTrue(resources.hasResourceItem(ResourceType.STYLE, "DarkActionBar"));
            ResourceItem style = getOnlyItem(resources, ResourceType.STYLE, "DarkActionBar");
            StyleResourceValue srv = (StyleResourceValue) style.getResourceValue(false);
            assertNotNull(srv);
            ResourceValue actionBarStyle = srv.getItem("background", true);
            assertNotNull(actionBarStyle);
            assertEquals("@android:color/transparent", actionBarStyle.getValue());
            //noinspection ConstantConditions
            assertEquals("Zoom", getOnlyItem(resources, ResourceType.STRING, "title_zoom").getResourceValue(false).getValue());
        }
    });
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) Document(com.intellij.openapi.editor.Document) PsiFile(com.intellij.psi.PsiFile) ResourceItem(com.android.ide.common.res2.ResourceItem) PsiDocumentManager(com.intellij.psi.PsiDocumentManager)

Example 72 with PsiDocumentManager

use of com.intellij.psi.PsiDocumentManager in project android by JetBrains.

the class ResourceFolderRepositoryTest method testEditDeclareStyleableAttr.

public void testEditDeclareStyleableAttr() throws Exception {
    // Check edits of the name in a <declare-styleable> element.
    resetScanCounter();
    VirtualFile file1 = myFixture.copyFileToProject(VALUES1, "res/values/myvalues.xml");
    PsiFile psiFile1 = PsiManager.getInstance(getProject()).findFile(file1);
    assertNotNull(psiFile1);
    ResourceFolderRepository resources = createRepository();
    assertNotNull(resources);
    assertTrue(resources.hasResourceItem(ResourceType.DECLARE_STYLEABLE, "MyCustomView"));
    assertTrue(resources.hasResourceItem(ResourceType.ATTR, "watchType"));
    ResourceItem style = getOnlyItem(resources, ResourceType.DECLARE_STYLEABLE, "MyCustomView");
    DeclareStyleableResourceValue srv = (DeclareStyleableResourceValue) style.getResourceValue(false);
    assertNotNull(srv);
    assertEquals(5, srv.getAllAttributes().size());
    AttrResourceValue watchType = findAttr(srv.getAllAttributes(), "watchType");
    assertNotNull(watchType);
    assertEquals(2, watchType.getAttributeValues().size());
    assertEquals(Integer.valueOf(1), watchType.getAttributeValues().get("type_stopwatch"));
    assertEquals(Integer.valueOf(0), watchType.getAttributeValues().get("type_countdown"));
    AttrResourceValue crash = findAttr(srv.getAllAttributes(), "crash");
    assertNotNull(crash);
    assertNull(crash.getAttributeValues());
    AttrResourceValue minWidth = findAttr(srv.getAllAttributes(), "minWidth");
    assertNotNull(minWidth);
    assertFalse(resources.hasResourceItem(ResourceType.ATTR, "minWidth"));
    AttrResourceValue ignoredNoFormat = findAttr(srv.getAllAttributes(), "ignore_no_format");
    assertNotNull(ignoredNoFormat);
    assertFalse(resources.hasResourceItem(ResourceType.ATTR, "ignore_no_format"));
    long generation = resources.getModificationCount();
    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
    final Document document = documentManager.getDocument(psiFile1);
    assertNotNull(document);
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            int offset = document.getText().indexOf("MyCustomView");
            document.insertString(offset + 8, "r");
            documentManager.commitDocument(document);
        }
    });
    // First edit won't be incremental (file -> Psi).
    assertTrue(resources.isScanPending(psiFile1));
    UIUtil.dispatchAllInvocationEvents();
    assertTrue(generation < resources.getModificationCount());
    assertTrue(resources.hasResourceItem(ResourceType.DECLARE_STYLEABLE, "MyCustomrView"));
    assertTrue(resources.hasResourceItem(ResourceType.ATTR, "watchType"));
    assertFalse(resources.hasResourceItem(ResourceType.DECLARE_STYLEABLE, "MyCustomView"));
    resetScanCounter();
    // Now try another edit, where things should be incremental now.
    final long generation2 = resources.getModificationCount();
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            int offset = document.getText().indexOf("MyCustomrView");
            document.insertString(offset + 8, "e");
            documentManager.commitDocument(document);
        }
    });
    assertTrue(generation2 < resources.getModificationCount());
    assertTrue(resources.hasResourceItem(ResourceType.DECLARE_STYLEABLE, "MyCustomerView"));
    assertTrue(resources.hasResourceItem(ResourceType.ATTR, "watchType"));
    assertFalse(resources.hasResourceItem(ResourceType.DECLARE_STYLEABLE, "MyCustomView"));
    style = getOnlyItem(resources, ResourceType.DECLARE_STYLEABLE, "MyCustomerView");
    srv = (DeclareStyleableResourceValue) style.getResourceValue(false);
    assertNotNull(srv);
    assertEquals(5, srv.getAllAttributes().size());
    watchType = findAttr(srv.getAllAttributes(), "watchType");
    assertNotNull(watchType);
    assertEquals(2, watchType.getAttributeValues().size());
    assertEquals(Integer.valueOf(1), watchType.getAttributeValues().get("type_stopwatch"));
    // Shouldn't have done any full file rescans during the above edits
    ensureIncremental();
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) PsiFile(com.intellij.psi.PsiFile) ResourceItem(com.android.ide.common.res2.ResourceItem) Document(com.intellij.openapi.editor.Document) PsiDocumentManager(com.intellij.psi.PsiDocumentManager)

Example 73 with PsiDocumentManager

use of com.intellij.psi.PsiDocumentManager in project android by JetBrains.

the class ResourceFolderRepositoryTest method testEditLayoutNoOp.

public void testEditLayoutNoOp() throws Exception {
    resetScanCounter();
    // Make some miscellaneous edits in the file that have no bearing on the
    // project resources and therefore end up doing no work
    VirtualFile file1 = myFixture.copyFileToProject(LAYOUT1, "res/layout/layout1.xml");
    final PsiFile psiFile1 = PsiManager.getInstance(getProject()).findFile(file1);
    assertNotNull(psiFile1);
    assert (psiFile1 instanceof XmlFile);
    final XmlFile xmlFile = (XmlFile) psiFile1;
    final ResourceFolderRepository resources = createRepository();
    assertNotNull(resources);
    Collection<String> layouts = resources.getItemsOfType(ResourceType.LAYOUT);
    assertEquals(1, layouts.size());
    assertNotNull(resources.getResourceItem(ResourceType.LAYOUT, "layout1"));
    final long initial = resources.getModificationCount();
    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
    final Document document = documentManager.getDocument(psiFile1);
    assertNotNull(document);
    // Insert a comment at the beginning
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            XmlTag rootTag = xmlFile.getRootTag();
            assertNotNull(rootTag);
            int rootTagOffset = rootTag.getTextOffset();
            document.insertString(rootTagOffset, "<!-- This is a\nmultiline comment -->");
            documentManager.commitDocument(document);
            // Edit the comment some more
            document.deleteString(rootTagOffset + 8, rootTagOffset + 8 + 5);
            documentManager.commitDocument(document);
            document.insertString(rootTagOffset + 8, "Replacement");
            documentManager.commitDocument(document);
        }
    });
    // Inserting the comment and editing it shouldn't have had any observable results on the resource repository
    assertEquals(initial, resources.getModificationCount());
    assertTrue(resources.hasResourceItem(ResourceType.ID, "noteArea"));
    final XmlTag tag = findTagById(psiFile1, "noteArea");
    assertNotNull(tag);
    // Now insert some whitespace before a tag
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            int indentAreaBeforeTag = tag.getTextOffset() - 1;
            document.insertString(indentAreaBeforeTag, "   ");
            documentManager.commitDocument(document);
            document.deleteString(indentAreaBeforeTag, indentAreaBeforeTag + 2);
            documentManager.commitDocument(document);
        }
    });
    // Space edits outside the tag shouldn't be observable
    assertEquals(initial, resources.getModificationCount());
    // Edit text inside an element tag. No effect in value files!
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            final XmlTag header = findTagById(xmlFile, "header");
            assertNotNull(header);
            int indentAreaBeforeTag = header.getSubTags()[0].getTextOffset();
            document.insertString(indentAreaBeforeTag, "   ");
            documentManager.commitDocument(document);
        }
    });
    // Space edits inside the tag shouldn't be observable
    assertEquals(initial, resources.getModificationCount());
    // Insert tag (without id) in layout file: ignored (only ids and file item matters)
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            final XmlTag header = findTagById(xmlFile, "text2");
            assertNotNull(header);
            int indentAreaBeforeTag = header.getTextOffset() - 1;
            document.insertString(indentAreaBeforeTag, "<Button />");
            documentManager.commitDocument(document);
        }
    });
    // Non-id new tags shouldn't be observable
    assertEquals(initial, resources.getModificationCount());
    // Shouldn't have done any full file rescans during the above edits
    ensureIncremental();
    // Finally make an edit which *does* affect the project resources to ensure
    // that document edits actually *do* fire PSI events that are digested by
    // this repository
    assertFalse(resources.hasResourceItem(ResourceType.ID, "newid"));
    final String elementDeclaration = "<Button android:id=\"@+id/newid\" />\n";
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            final XmlTag tag = findTagById(psiFile1, "noteArea");
            assertNotNull(tag);
            document.insertString(tag.getTextOffset() - 1, elementDeclaration);
            documentManager.commitDocument(document);
        }
    });
    // First edit won't be incremental (file -> Psi).
    assertTrue(resources.isScanPending(psiFile1));
    UIUtil.dispatchAllInvocationEvents();
    assertTrue(resources.hasResourceItem(ResourceType.ID, "newid"));
    assertFalse(resources.hasResourceItem(ResourceType.ID, "newid2"));
    assertTrue(resources.getModificationCount() > initial);
    resetScanCounter();
    // Now try another edit, where things should be incremental now.
    long generation = resources.getModificationCount();
    final String elementDeclaration2 = "<Button android:id=\"@+id/newid2\" />\n";
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            final XmlTag tag = findTagById(psiFile1, "noteArea");
            assertNotNull(tag);
            document.insertString(tag.getTextOffset() - 1, elementDeclaration2);
            documentManager.commitDocument(document);
        }
    });
    assertFalse(resources.isScanPending(psiFile1));
    assertTrue(resources.hasResourceItem(ResourceType.ID, "newid"));
    assertTrue(resources.hasResourceItem(ResourceType.ID, "newid2"));
    assertTrue(resources.getModificationCount() > generation);
    ensureIncremental();
    final long generation2 = resources.getModificationCount();
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            int startOffset = document.getText().indexOf(elementDeclaration);
            document.deleteString(startOffset, startOffset + elementDeclaration.length());
            documentManager.commitDocument(document);
        }
    });
    assertTrue(resources.isScanPending(psiFile1));
    resetScanCounter();
    ApplicationManager.getApplication().invokeLater(new Runnable() {

        @Override
        public void run() {
            ensureSingleScan();
            assertFalse(resources.hasResourceItem(ResourceType.ID, "newid"));
            assertTrue(resources.getModificationCount() > generation2);
        }
    });
    UIUtil.dispatchAllInvocationEvents();
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) XmlFile(com.intellij.psi.xml.XmlFile) PsiFile(com.intellij.psi.PsiFile) Document(com.intellij.openapi.editor.Document) PsiDocumentManager(com.intellij.psi.PsiDocumentManager) XmlTag(com.intellij.psi.xml.XmlTag)

Example 74 with PsiDocumentManager

use of com.intellij.psi.PsiDocumentManager in project android by JetBrains.

the class ResourceFolderRepositoryTest method testBreakNameAttribute.

public void testBreakNameAttribute() throws Exception {
    resetScanCounter();
    VirtualFile file1 = myFixture.copyFileToProject(VALUES1, "res/values/myvalues.xml");
    PsiFile psiFile1 = PsiManager.getInstance(getProject()).findFile(file1);
    assertNotNull(psiFile1);
    final ResourceFolderRepository resources = createRepository();
    assertNotNull(resources);
    assertTrue(resources.hasResourceItem(ResourceType.STRING, "app_name"));
    final long generation = resources.getModificationCount();
    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
    final Document document = documentManager.getDocument(psiFile1);
    assertNotNull(document);
    final int offset = document.getText().indexOf("name=\"app_name\">");
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            // name => nome
            document.replaceString(offset + 2, offset + 3, "o");
            documentManager.commitDocument(document);
        }
    });
    assertTrue(resources.isScanPending(psiFile1));
    UIUtil.dispatchAllInvocationEvents();
    UIUtil.invokeAndWaitIfNeeded(new Runnable() {

        @Override
        public void run() {
            ensureSingleScan();
            assertTrue(generation < resources.getModificationCount());
            assertFalse(resources.hasResourceItem(ResourceType.STRING, "app_name"));
        }
    });
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) PsiFile(com.intellij.psi.PsiFile) Document(com.intellij.openapi.editor.Document) PsiDocumentManager(com.intellij.psi.PsiDocumentManager)

Example 75 with PsiDocumentManager

use of com.intellij.psi.PsiDocumentManager in project android by JetBrains.

the class ResourceFolderRepositoryTest method testNestedEditValueText.

public void testNestedEditValueText() throws Exception {
    resetScanCounter();
    VirtualFile file1 = myFixture.copyFileToProject(VALUES1, "res/values/myvalues.xml");
    PsiFile psiFile1 = PsiManager.getInstance(getProject()).findFile(file1);
    assertNotNull(psiFile1);
    ResourceFolderRepository resources = createRepository();
    assertNotNull(resources);
    List<ResourceItem> labelList = resources.getResourceItem(ResourceType.STRING, "title_template_step");
    assertNotNull(labelList);
    assertEquals(1, labelList.size());
    ResourceItem label = labelList.get(0);
    ResourceValue resourceValue = label.getResourceValue(false);
    assertNotNull(resourceValue);
    assertEquals("Step ${step_number}: Lorem Ipsum", resourceValue.getValue());
    long generation = resources.getModificationCount();
    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(getProject());
    final Document document = documentManager.getDocument(psiFile1);
    assertNotNull(document);
    // Edit value should cause update
    final int textOffset = document.getText().indexOf("Lorem");
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            document.insertString(textOffset + 1, "l");
            documentManager.commitDocument(document);
        }
    });
    // First edit won't be incremental (file -> Psi).
    assertTrue(resources.isScanPending(psiFile1));
    UIUtil.dispatchAllInvocationEvents();
    assertTrue(generation < resources.getModificationCount());
    // Because of the file -> psi transition, we can't rely on the old ResourceItem references (replaced).
    // We need to ensure that callers don't hang on to the old ResourceItem, assuming it'll get
    // updated in place after an edit.
    labelList = resources.getResourceItem(ResourceType.STRING, "title_template_step");
    assertNotNull(labelList);
    assertEquals(1, labelList.size());
    label = labelList.get(0);
    resourceValue = label.getResourceValue(false);
    assertNotNull(resourceValue);
    assertEquals("Step ${step_number}: Llorem Ipsum", resourceValue.getValue());
    resetScanCounter();
    // Try a second edit
    long generation2 = resources.getModificationCount();
    WriteCommandAction.runWriteCommandAction(null, new Runnable() {

        @Override
        public void run() {
            int textOffset2 = document.getText().indexOf("Llorem");
            document.insertString(textOffset + 1, "l");
            documentManager.commitDocument(document);
        }
    });
    assertTrue(generation2 < resources.getModificationCount());
    List<ResourceItem> labelList2 = resources.getResourceItem(ResourceType.STRING, "title_template_step");
    assertNotNull(labelList2);
    assertEquals(1, labelList2.size());
    final ResourceItem label2 = labelList2.get(0);
    resourceValue = label2.getResourceValue(false);
    assertNotNull(resourceValue);
    assertEquals("Step ${step_number}: Lllorem Ipsum", resourceValue.getValue());
    // Shouldn't have done any full file rescans during the above edits
    ensureIncremental();
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) PsiFile(com.intellij.psi.PsiFile) ResourceItem(com.android.ide.common.res2.ResourceItem) Document(com.intellij.openapi.editor.Document) PsiDocumentManager(com.intellij.psi.PsiDocumentManager)

Aggregations

PsiDocumentManager (com.intellij.psi.PsiDocumentManager)140 Document (com.intellij.openapi.editor.Document)111 PsiFile (com.intellij.psi.PsiFile)100 VirtualFile (com.intellij.openapi.vfs.VirtualFile)51 ResourceItem (com.android.ide.common.res2.ResourceItem)26 PsiElement (com.intellij.psi.PsiElement)24 Project (com.intellij.openapi.project.Project)22 TextRange (com.intellij.openapi.util.TextRange)13 NotNull (org.jetbrains.annotations.NotNull)12 Nullable (org.jetbrains.annotations.Nullable)9 IncorrectOperationException (com.intellij.util.IncorrectOperationException)8 Editor (com.intellij.openapi.editor.Editor)7 XmlFile (com.intellij.psi.xml.XmlFile)6 FileType (com.intellij.openapi.fileTypes.FileType)5 XmlTag (com.intellij.psi.xml.XmlTag)5 ASTNode (com.intellij.lang.ASTNode)3 GroovyPsiElementFactory (org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory)3 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)2 DocumentEx (com.intellij.openapi.editor.ex.DocumentEx)2 EditorEx (com.intellij.openapi.editor.ex.EditorEx)2