diff --git a/jps/model-serialization/src/com/intellij/openapi/application/PathMacroFilter.java b/jps/model-serialization/src/com/intellij/openapi/application/PathMacroFilter.java
index e5f4ca26e492..f6beb95d4239 100644
--- a/jps/model-serialization/src/com/intellij/openapi/application/PathMacroFilter.java
+++ b/jps/model-serialization/src/com/intellij/openapi/application/PathMacroFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,9 @@
package com.intellij.openapi.application;
import org.jdom.Attribute;
+import org.jdom.Element;
import org.jdom.Text;
+import org.jetbrains.annotations.NotNull;
/**
* Allows to disable expansion of path macros in the values of certain properties.
@@ -24,6 +26,9 @@ import org.jdom.Text;
* @author yole
*/
public abstract class PathMacroFilter {
+ public boolean skipPathMacros(@NotNull Element element) {
+ return false;
+ }
public boolean skipPathMacros(Text element) {
return false;
diff --git a/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java b/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
index 781d0f9ebdaf..ba6b779a3766 100644
--- a/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
+++ b/jps/model-serialization/src/com/intellij/openapi/components/PathMacroMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2015 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,10 @@ public abstract class PathMacroMap {
}
public final void substitute(@NotNull Element e, boolean caseSensitive, boolean recursively, @Nullable PathMacroFilter filter) {
+ if (filter != null && filter.skipPathMacros(e)) {
+ return;
+ }
+
for (Content child : e.getContent()) {
if (child instanceof Element) {
substitute((Element)child, caseSensitive, recursively, filter);
diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectSettingsBase.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectSettingsBase.java
index 428b79f71341..b1120fc9d2fd 100644
--- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectSettingsBase.java
+++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectSettingsBase.java
@@ -15,12 +15,15 @@
*/
package com.intellij.find.impl;
+import com.intellij.openapi.application.PathMacroFilter;
import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.openapi.components.impl.stores.FileStorageCoreUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.xmlb.XmlSerializerUtil;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Property;
import com.intellij.util.xmlb.annotations.Tag;
+import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -115,4 +118,17 @@ public class FindInProjectSettingsBase implements PersistentStateComponent
+
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/CompositePathMacroFilter.java b/platform/projectModel-impl/src/com/intellij/openapi/components/CompositePathMacroFilter.java
index ae134d493fb2..93bd2a16f317 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/components/CompositePathMacroFilter.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/components/CompositePathMacroFilter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,9 @@ package com.intellij.openapi.components;
import com.intellij.openapi.application.PathMacroFilter;
import org.jdom.Attribute;
+import org.jdom.Element;
import org.jdom.Text;
+import org.jetbrains.annotations.NotNull;
/**
* @author yole
@@ -29,6 +31,16 @@ public class CompositePathMacroFilter extends PathMacroFilter {
myFilters = filters;
}
+ @Override
+ public boolean skipPathMacros(@NotNull Element element) {
+ for (PathMacroFilter filter : myFilters) {
+ if (filter.skipPathMacros(element)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@Override
public boolean skipPathMacros(Text element) {
for (PathMacroFilter filter : myFilters) {
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/FileStorageCoreUtil.java b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/FileStorageCoreUtil.java
index 1be7ff22a76e..7ba9ad1d35e4 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/FileStorageCoreUtil.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/components/impl/stores/FileStorageCoreUtil.java
@@ -16,17 +16,21 @@
package com.intellij.openapi.components.impl.stores;
import com.intellij.application.options.PathMacrosCollector;
+import com.intellij.openapi.application.PathMacros;
+import com.intellij.openapi.components.CompositePathMacroFilter;
import com.intellij.openapi.components.PathMacroSubstitutor;
import com.intellij.openapi.components.TrackingPathMacroSubstitutor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.SmartList;
import com.intellij.util.containers.StringInterner;
import org.jdom.Element;
+import org.jdom.Parent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import java.util.TreeMap;
@@ -47,16 +51,23 @@ public class FileStorageCoreUtil {
List children = rootElement.getChildren(COMPONENT);
if (children.isEmpty() && rootElement.getName().equals(COMPONENT) && rootElement.getAttributeValue(NAME) != null) {
// exclusive component data
- children = Collections.singletonList(rootElement);
+ // singleton must be not used here - later we modify list
+ children = new SmartList<>(rootElement);
}
+ CompositePathMacroFilter filter = null;
+
TreeMap map = new TreeMap<>();
- for (Element element : children) {
+ for (Iterator iterator = children.iterator(); iterator.hasNext(); ) {
+ Element element = iterator.next();
String name = getComponentNameIfValid(element);
if (name == null || !(element.getAttributes().size() > 1 || !element.getChildren().isEmpty())) {
continue;
}
+ // so, PathMacroFilter can easily find component name (null parent)
+ iterator.remove();
+
if (interner != null) {
JDOMUtil.internElement(element, interner);
}
@@ -64,7 +75,12 @@ public class FileStorageCoreUtil {
map.put(name, element);
if (pathMacroSubstitutor instanceof TrackingPathMacroSubstitutor) {
- ((TrackingPathMacroSubstitutor)pathMacroSubstitutor).addUnknownMacros(name, PathMacrosCollector.getMacroNames(element));
+ if (filter == null) {
+ filter = new CompositePathMacroFilter(PathMacrosCollector.MACRO_FILTER_EXTENSION_POINT_NAME.getExtensions());
+ }
+
+ ((TrackingPathMacroSubstitutor)pathMacroSubstitutor)
+ .addUnknownMacros(name, PathMacrosCollector.getMacroNames(element, filter, PathMacros.getInstance()));
}
// remove only after "getMacroNames" - some PathMacroFilter requires element name attribute
@@ -82,4 +98,19 @@ public class FileStorageCoreUtil {
}
return name;
}
+
+ @Nullable
+ public static String findComponentName(@NotNull Element element) {
+ Element componentElement = element;
+ while (true) {
+ Parent parent = componentElement.getParent();
+ if (parent == null || !(parent instanceof Element)) {
+ break;
+ }
+
+ componentElement = (Element)parent;
+ }
+
+ return StringUtil.nullize(componentElement.getAttributeValue(NAME));
+ }
}