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());
}
});
}
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();
}
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();
}
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"));
}
});
}
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();
}
Aggregations