Search in sources :

Example 96 with XmlFile

use of com.intellij.psi.xml.XmlFile in project intellij-community by JetBrains.

the class SmartPsiElementPointersTest method testManyPsiChangesWithManySmartPointersPerformance.

public void testManyPsiChangesWithManySmartPointersPerformance() throws Exception {
    String eachTag = "<a>\n" + StringUtil.repeat("   <a> </a>\n", 9) + "</a>\n";
    XmlFile file = (XmlFile) createFile("a.xml", "<root>\n" + StringUtil.repeat(eachTag, 500) + "</root>");
    List<XmlTag> tags = ContainerUtil.newArrayList(PsiTreeUtil.findChildrenOfType(file.getDocument(), XmlTag.class));
    List<SmartPsiElementPointer> pointers = tags.stream().map(this::createPointer).collect(Collectors.toList());
    ApplicationManager.getApplication().runWriteAction(() -> PlatformTestUtil.startPerformanceTest("smart pointer range update after PSI change", 21000, () -> {
        for (int i = 0; i < tags.size(); i++) {
            XmlTag tag = tags.get(i);
            SmartPsiElementPointer pointer = pointers.get(i);
            assertEquals(tag.getName().length(), TextRange.create(pointer.getRange()).getLength());
            assertEquals(tag.getName().length(), TextRange.create(pointer.getPsiRange()).getLength());
            tag.setName("bar1" + (i % 10));
            assertEquals(tag.getName().length(), TextRange.create(pointer.getRange()).getLength());
            assertEquals(tag.getName().length(), TextRange.create(pointer.getPsiRange()).getLength());
        }
        PostprocessReformattingAspect.getInstance(myProject).doPostponedFormatting();
    }).cpuBound().useLegacyScaling().assertTiming());
}
Also used : XmlFile(com.intellij.psi.xml.XmlFile) XmlTag(com.intellij.psi.xml.XmlTag)

Example 97 with XmlFile

use of com.intellij.psi.xml.XmlFile in project intellij-plugins by JetBrains.

the class FlexResolveHelper method importClass.

public boolean importClass(final PsiScopeProcessor processor, final PsiNamedElement file) {
    // there is no need to process package stuff at function level
    if (file instanceof JSFunction)
        return true;
    if (file instanceof XmlBackedJSClassImpl) {
        if (!processInlineComponentsInScope((XmlBackedJSClassImpl) file, inlineComponent -> processor.execute(inlineComponent, ResolveState.initial()))) {
            return false;
        }
    }
    final String packageQualifierText = JSResolveUtil.findPackageStatementQualifier(file);
    final Project project = file.getProject();
    GlobalSearchScope scope = JSResolveUtil.getResolveScope(file);
    final MxmlAndFxgFilesProcessor filesProcessor = new MxmlAndFxgFilesProcessor() {

        final PsiManager manager = PsiManager.getInstance(project);

        public void addDependency(final PsiDirectory directory) {
        }

        public boolean processFile(final VirtualFile file, final VirtualFile root) {
            final PsiFile xmlFile = manager.findFile(file);
            if (!(xmlFile instanceof XmlFile))
                return true;
            return processor.execute(XmlBackedJSClassFactory.getXmlBackedClass((XmlFile) xmlFile), ResolveState.initial());
        }
    };
    PsiFile containingFile = file.getContainingFile();
    boolean completion = containingFile.getOriginalFile() != containingFile;
    if (completion) {
        return processAllMxmlAndFxgFiles(scope, project, filesProcessor, null);
    } else {
        if (packageQualifierText != null && packageQualifierText.length() > 0) {
            if (!processMxmlAndFxgFilesInPackage(scope, project, packageQualifierText, filesProcessor))
                return false;
        }
        return processMxmlAndFxgFilesInPackage(scope, project, "", filesProcessor);
    }
}
Also used : XmlBackedJSClassImpl(com.intellij.lang.javascript.flex.XmlBackedJSClassImpl) JavaScriptSupportLoader(com.intellij.lang.javascript.JavaScriptSupportLoader) XmlFile(com.intellij.psi.xml.XmlFile) JSChangeUtil(com.intellij.lang.javascript.psi.impl.JSChangeUtil) VirtualFile(com.intellij.openapi.vfs.VirtualFile) ProjectFileIndex(com.intellij.openapi.roots.ProjectFileIndex) FilenameIndex(com.intellij.psi.search.FilenameIndex) ContainerUtil(com.intellij.util.containers.ContainerUtil) ResolveProcessor(com.intellij.lang.javascript.psi.resolve.ResolveProcessor) DirectoryIndex(com.intellij.openapi.roots.impl.DirectoryIndex) Query(com.intellij.util.Query) Project(com.intellij.openapi.project.Project) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) JSResolveHelper(com.intellij.lang.javascript.flex.JSResolveHelper) ProjectRootManager(com.intellij.openapi.roots.ProjectRootManager) CssString(com.intellij.psi.css.CssString) JSFile(com.intellij.lang.javascript.psi.JSFile) XmlTag(com.intellij.psi.xml.XmlTag) PsiScopeProcessor(com.intellij.psi.scope.PsiScopeProcessor) com.intellij.lang.javascript.psi.ecmal4(com.intellij.lang.javascript.psi.ecmal4) JSImportHandlingUtil(com.intellij.lang.javascript.psi.resolve.JSImportHandlingUtil) JSReferenceExpression(com.intellij.lang.javascript.psi.JSReferenceExpression) VfsUtilCore(com.intellij.openapi.vfs.VfsUtilCore) JSResolveUtil(com.intellij.lang.javascript.psi.resolve.JSResolveUtil) StringUtil(com.intellij.openapi.util.text.StringUtil) Collection(java.util.Collection) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) JSPsiImplUtils(com.intellij.lang.javascript.psi.impl.JSPsiImplUtils) ImportUtils(com.intellij.lang.javascript.flex.ImportUtils) ASTNode(com.intellij.lang.ASTNode) Nullable(org.jetbrains.annotations.Nullable) JSFunction(com.intellij.lang.javascript.psi.JSFunction) JarFileSystem(com.intellij.openapi.vfs.JarFileSystem) Processor(com.intellij.util.Processor) MxmlJSClassProvider(com.intellij.javascript.flex.mxml.MxmlJSClassProvider) com.intellij.psi(com.intellij.psi) Ref(com.intellij.openapi.util.Ref) VirtualFile(com.intellij.openapi.vfs.VirtualFile) XmlBackedJSClassImpl(com.intellij.lang.javascript.flex.XmlBackedJSClassImpl) XmlFile(com.intellij.psi.xml.XmlFile) CssString(com.intellij.psi.css.CssString) Project(com.intellij.openapi.project.Project) JSFunction(com.intellij.lang.javascript.psi.JSFunction) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope)

Example 98 with XmlFile

use of com.intellij.psi.xml.XmlFile in project android by JetBrains.

the class LayoutPsiPullParserTest method testEmptyLayout.

public void testEmptyLayout() throws XmlPullParserException {
    XmlFile emptyFile = mock(XmlFile.class);
    when(emptyFile.getRootTag()).thenReturn(null);
    RenderLogger logger = new RenderLogger("test", myModule);
    assertEmptyParser(LayoutPsiPullParser.create(emptyFile, logger));
    XmlTag emptyTag = mock(XmlTag.class);
    assertEmptyParser(new LayoutPsiPullParser(mock(XmlTag.class), logger));
    when(emptyTag.isValid()).thenReturn(true);
    assertEmptyParser(new LayoutPsiPullParser(mock(XmlTag.class), logger));
}
Also used : XmlFile(com.intellij.psi.xml.XmlFile) XmlTag(com.intellij.psi.xml.XmlTag)

Example 99 with XmlFile

use of com.intellij.psi.xml.XmlFile in project android by JetBrains.

the class LayoutPsiPullParserTest method testDesignAttributes.

public void testDesignAttributes() throws Exception {
    @SuppressWarnings("SpellCheckingInspection") VirtualFile virtualFile = myFixture.copyFileToProject("xmlpull/designtime.xml", "res/layout/designtime.xml");
    assertNotNull(virtualFile);
    PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(virtualFile);
    assertTrue(psiFile instanceof XmlFile);
    XmlFile xmlFile = (XmlFile) psiFile;
    LayoutPsiPullParser parser = LayoutPsiPullParser.create(xmlFile, new RenderLogger("test", myModule));
    assertEquals(START_TAG, parser.nextTag());
    assertEquals("LinearLayout", parser.getName());
    assertEquals(START_TAG, parser.nextTag());
    assertEquals("TextView", parser.getName());
    assertEquals("@+id/first", parser.getAttributeValue(ANDROID_URI, ATTR_ID));
    assertEquals(END_TAG, parser.nextTag());
    assertEquals(START_TAG, parser.nextTag());
    assertEquals("TextView", parser.getName());
    // auto converted from match_parent
    assertEquals("fill_parent", parser.getAttributeValue(ANDROID_URI, ATTR_LAYOUT_WIDTH));
    assertEquals("wrap_content", parser.getAttributeValue(ANDROID_URI, ATTR_LAYOUT_HEIGHT));
    // overriding runtime text attribute
    assertEquals("Designtime Text", parser.getAttributeValue(ANDROID_URI, ATTR_TEXT));
    assertEquals("@android:color/darker_gray", parser.getAttributeValue(ANDROID_URI, "textColor"));
    assertEquals(END_TAG, parser.nextTag());
    assertEquals(START_TAG, parser.nextTag());
    assertEquals("TextView", parser.getName());
    assertEquals("@+id/blank", parser.getAttributeValue(ANDROID_URI, ATTR_ID));
    // Don't unset when no framework attribute is defined
    assertEquals("", parser.getAttributeValue(ANDROID_URI, ATTR_TEXT));
    assertEquals(END_TAG, parser.nextTag());
    assertEquals(START_TAG, parser.nextTag());
    assertEquals("ListView", parser.getName());
    assertEquals("@+id/listView", parser.getAttributeValue(ANDROID_URI, ATTR_ID));
    // Cleared by overriding defined framework attribute
    assertNull(parser.getAttributeValue(ANDROID_URI, "fastScrollAlwaysVisible"));
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) XmlFile(com.intellij.psi.xml.XmlFile) PsiFile(com.intellij.psi.PsiFile)

Example 100 with XmlFile

use of com.intellij.psi.xml.XmlFile in project android by JetBrains.

the class ResourceNotificationManagerTest method test.

public void test() {
    @Language("XML") String xml;
    // Setup sample project: a strings file, and a couple of layout file
    xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + "    android:layout_width=\"match_parent\"\n" + "    android:layout_height=\"match_parent\">\n" + "    <!-- My comment -->\n" + "    <TextView " + "        android:layout_width=\"match_parent\"\n" + "        android:layout_height=\"match_parent\"\n" + "        android:text=\"@string/hello\" />\n" + "</FrameLayout>";
    final XmlFile layout1 = (XmlFile) myFixture.addFileToProject("res/layout/my_layout1.xml", xml);
    @SuppressWarnings("ConstantConditions") VirtualFile resourceDir = layout1.getParent().getParent().getVirtualFile();
    assertNotNull(resourceDir);
    xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n" + "    android:layout_width=\"match_parent\"\n" + "    android:layout_height=\"match_parent\" />\n";
    final XmlFile layout2 = (XmlFile) myFixture.addFileToProject("res/layout/my_layout2.xml", xml);
    xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<resources>\n" + "    <string name=\"hello\">Hello</string>\n" + "\n" + "    <!-- Base application theme. -->\n" + "    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n" + "        <!-- Customize your theme here. -->\n" + "        <item name=\"android:colorBackground\">#ff0000</item>\n" + "    </style>" + "</resources>";
    final XmlFile values1 = (XmlFile) myFixture.addFileToProject("res/values/my_values1.xml", xml);
    xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<resources>\n" + "    \n" + "</resources>";
    myFixture.addFileToProject("res/values/colors.xml", xml);
    final Configuration configuration1 = myFacet.getConfigurationManager().getConfiguration(layout1.getVirtualFile());
    final ResourceNotificationManager manager = ResourceNotificationManager.getInstance(getProject());
    // Listener 1: Listens for changes in layout 1
    final Ref<Boolean> called1 = new Ref<>(false);
    final Ref<Set<Reason>> calledValue1 = new Ref<>();
    ResourceChangeListener listener1 = new ResourceChangeListener() {

        @Override
        public void resourcesChanged(@NotNull Set<Reason> reason) {
            called1.set(true);
            calledValue1.set(reason);
        }
    };
    // Listener 2: Only listens for general changes in the module
    final Ref<Boolean> called2 = new Ref<>(false);
    final Ref<Set<Reason>> calledValue2 = new Ref<>();
    ResourceChangeListener listener2 = new ResourceChangeListener() {

        @Override
        public void resourcesChanged(@NotNull Set<Reason> reason) {
            called2.set(true);
            calledValue2.set(reason);
        }
    };
    manager.addListener(listener1, myFacet, layout1, configuration1);
    manager.addListener(listener2, myFacet, null, null);
    // Make sure that when we're modifying multiple files, with complicated
    // edits (that trigger full file rescans), we handle that scenario correctly.
    clear(called1, calledValue1, called2, calledValue2);
    // There's actually some special optimizations done via PsiResourceItem#recomputeValue
    // to only mark the resource repository changed if the value has actually been looked
    // up. This allows us to not recompute layout if you're editing some string that
    // hasn't actually been looked up and rendered in a layout. In order to make sure
    // that that optimization doesn't kick in here, we need to look up the value of
    // the resource item first:
    //noinspection ConstantConditions
    assertEquals("#ff0000", configuration1.getResourceResolver().getStyle("AppTheme", false).getItem("colorBackground", true).getValue());
    AndroidResourceUtil.createValueResource(getProject(), resourceDir, "color2", ResourceType.COLOR, "colors.xml", Collections.singletonList("values"), "#fa2395");
    ensureCalled(called1, calledValue1, called2, calledValue2, Reason.RESOURCE_EDIT);
    clear(called1, calledValue1, called2, calledValue2);
    @SuppressWarnings("ConstantConditions") final XmlTag tag = values1.getDocument().getRootTag().getSubTags()[1].getSubTags()[0];
    assertEquals("item", tag.getName());
    WriteCommandAction.runWriteCommandAction(getProject(), new Runnable() {

        @Override
        public void run() {
            tag.getValue().setEscapedText("@color/color2");
        }
    });
    ensureCalled(called1, calledValue1, called2, calledValue2, Reason.RESOURCE_EDIT);
    // First check: Modify the layout by changing @string/hello to @string/hello_world
    // and verify that our listeners are called.
    ResourceVersion version1 = manager.getCurrentVersion(myFacet, layout1, configuration1);
    addText(layout1, "@string/hello^", "_world");
    ensureCalled(called1, calledValue1, called2, calledValue2, Reason.EDIT);
    ResourceVersion version2 = manager.getCurrentVersion(myFacet, layout1, configuration1);
    assertFalse(version1.toString(), version1.equals(version2));
    // Next check: Modify a <string> value definition in a values file
    // and check that those changes are flagged too
    clear(called1, calledValue1, called2, calledValue2);
    ResourceVersion version3 = manager.getCurrentVersion(myFacet, layout1, configuration1);
    addText(values1, "name=\"hello^\"", "_world");
    ensureCalled(called1, calledValue1, called2, calledValue2, Reason.RESOURCE_EDIT);
    ResourceVersion version4 = manager.getCurrentVersion(myFacet, layout1, configuration1);
    assertFalse(version4.toString(), version3.equals(version4));
    // Next check: Modify content in a comment and verify that no changes are fired
    clear(called1, calledValue1, called2, calledValue2);
    addText(layout1, "My ^comment", "new ");
    ensureNotCalled(called1, called2);
    // Check that editing text in a layout file has no effect
    clear(called1, calledValue1, called2, calledValue2);
    addText(layout1, " ^ <TextView", "abc");
    ensureNotCalled(called1, called2);
    // Make sure that's true for replacements too
    replaceText(layout1, "^abc", "abc".length(), "def");
    ensureNotCalled(called1, called2);
    // ...and for deletions
    removeText(layout1, "^def", "def".length());
    ensureNotCalled(called1, called2);
    // Check that editing text in a *values file* -does- have an effect
    // Read the value first to ensure that we trigger it as a read (see comment above for previous
    // resource resolver lookup)
    //noinspection ConstantConditions
    assertEquals("Hello", configuration1.getResourceResolver().findResValue("@string/hello_world", false).getValue());
    addText(values1, "Hello^</string>", " World");
    ensureCalled(called1, calledValue1, called2, calledValue2, Reason.RESOURCE_EDIT);
    // Check that recreating AppResourceRepository object doesn't affect the ResourceNotificationManager
    clear(called1, calledValue1, called2, calledValue2);
    myFacet.refreshResources();
    AndroidResourceUtil.createValueResource(getProject(), resourceDir, "color4", ResourceType.COLOR, "colors.xml", Collections.singletonList("values"), "#ff2300");
    ensureCalled(called1, calledValue1, called2, calledValue2, Reason.RESOURCE_EDIT);
    // Finally check that once we remove the listeners there are no more notifications
    manager.removeListener(listener1, myFacet, layout1, configuration1);
    manager.removeListener(listener2, myFacet, layout2, configuration1);
    clear(called1, calledValue1, called2, calledValue2);
    addText(layout1, "@string/hello_world^", "2");
    ensureNotCalled(called1, called2);
// TODO: Check that editing a partial URL doesn't re-render
// Check module dependency triggers!
// TODO: Test that remove and replace editing also works as expected
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) Set(java.util.Set) EnumSet(java.util.EnumSet) XmlFile(com.intellij.psi.xml.XmlFile) Configuration(com.android.tools.idea.configurations.Configuration) ResourceVersion(com.android.tools.idea.res.ResourceNotificationManager.ResourceVersion) NotNull(org.jetbrains.annotations.NotNull) Ref(com.intellij.openapi.util.Ref) Language(org.intellij.lang.annotations.Language) ResourceChangeListener(com.android.tools.idea.res.ResourceNotificationManager.ResourceChangeListener) XmlTag(com.intellij.psi.xml.XmlTag)

Aggregations

XmlFile (com.intellij.psi.xml.XmlFile)409 XmlTag (com.intellij.psi.xml.XmlTag)155 PsiFile (com.intellij.psi.PsiFile)121 VirtualFile (com.intellij.openapi.vfs.VirtualFile)102 Nullable (org.jetbrains.annotations.Nullable)74 Project (com.intellij.openapi.project.Project)69 NotNull (org.jetbrains.annotations.NotNull)66 PsiElement (com.intellij.psi.PsiElement)64 XmlAttribute (com.intellij.psi.xml.XmlAttribute)39 WriteCommandAction (com.intellij.openapi.command.WriteCommandAction)34 Module (com.intellij.openapi.module.Module)34 XmlDocument (com.intellij.psi.xml.XmlDocument)32 Result (com.intellij.openapi.application.Result)28 XmlElementDescriptor (com.intellij.xml.XmlElementDescriptor)23 XmlAttributeValue (com.intellij.psi.xml.XmlAttributeValue)22 XmlNSDescriptor (com.intellij.xml.XmlNSDescriptor)21 ArrayList (java.util.ArrayList)20 Document (com.intellij.openapi.editor.Document)19 AndroidFacet (org.jetbrains.android.facet.AndroidFacet)18 Editor (com.intellij.openapi.editor.Editor)15