mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -24,6 +24,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -174,8 +175,9 @@ public class AndroidResourcesLineMarkerProvider implements LineMarkerProvider {
|
||||
private static Map<MyResourceEntry, List<PsiElement>> buildLocalResourceMap(@NotNull Project project,
|
||||
@NotNull final LocalResourceManager resManager) {
|
||||
final Map<MyResourceEntry, List<PsiElement>> result = new HashMap<MyResourceEntry, List<PsiElement>>();
|
||||
Collection<Resources> resourceFiles = resManager.getResourceElements();
|
||||
for (Resources res : resourceFiles) {
|
||||
List<Pair<Resources,VirtualFile>> resourceFiles = resManager.getResourceElements();
|
||||
for (Pair<Resources, VirtualFile> pair : resourceFiles) {
|
||||
final Resources res = pair.getFirst();
|
||||
for (ResourceType valueResourceType : AndroidResourceUtil.VALUE_RESOURCE_TYPES) {
|
||||
for (ResourceElement valueResource : AndroidResourceUtil.getValueResourcesFromElement(valueResourceType.getName(), res)) {
|
||||
addResource(valueResourceType.getName(), valueResource, result);
|
||||
|
||||
@@ -729,8 +729,9 @@ public class AndroidCompileUtil {
|
||||
}
|
||||
}
|
||||
|
||||
for (final Resources resources : manager.getResourceElements()) {
|
||||
waitForSmartMode(project);
|
||||
for (final Pair<Resources, VirtualFile> pair : manager.getResourceElements()) {
|
||||
final Resources resources = pair.getFirst();
|
||||
waitForSmartMode(project);
|
||||
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
|
||||
+160
-19
@@ -1,29 +1,44 @@
|
||||
package org.jetbrains.android.compiler;
|
||||
|
||||
import com.android.resources.ResourceType;
|
||||
import com.android.sdklib.IAndroidTarget;
|
||||
import com.intellij.openapi.compiler.ValidityState;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.ContentIterator;
|
||||
import com.intellij.openapi.roots.impl.FileIndexImplUtil;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.openapi.vfs.VirtualFileFilter;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.android.dom.resources.ResourceElement;
|
||||
import org.jetbrains.android.dom.resources.Resources;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.facet.AndroidRootUtil;
|
||||
import org.jetbrains.android.resourceManagers.LocalResourceManager;
|
||||
import org.jetbrains.android.resourceManagers.ResourceManager;
|
||||
import org.jetbrains.android.sdk.AndroidPlatform;
|
||||
import org.jetbrains.android.util.AndroidResourceUtil;
|
||||
import org.jetbrains.android.util.ResourceEntry;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class ResourceNamesValidityState implements ValidityState {
|
||||
private final Set<ResourceEntry> myResourcesSet = new HashSet<ResourceEntry>();
|
||||
private final Map<String, MyResourceFileData> myResources = new HashMap<String, MyResourceFileData>();
|
||||
|
||||
private final String myAndroidTargetHashString;
|
||||
private final long myManifestTimestamp;
|
||||
|
||||
|
||||
public ResourceNamesValidityState(@NotNull Module module) {
|
||||
final AndroidFacet facet = AndroidFacet.getInstance(module);
|
||||
assert facet != null;
|
||||
@@ -35,19 +50,83 @@ public class ResourceNamesValidityState implements ValidityState {
|
||||
final VirtualFile manifestFile = AndroidRootUtil.getManifestFile(facet);
|
||||
myManifestTimestamp = manifestFile != null ? manifestFile.getModificationStamp() : -1;
|
||||
|
||||
AndroidCompileUtil.collectAllResources(facet, myResourcesSet);
|
||||
final LocalResourceManager manager = facet.getLocalResourceManager();
|
||||
|
||||
for (final Pair<Resources, VirtualFile> pair : manager.getResourceElements()) {
|
||||
final Resources resources = pair.getFirst();
|
||||
final VirtualFile file = pair.getSecond();
|
||||
|
||||
for (final ResourceType resType : AndroidResourceUtil.VALUE_RESOURCE_TYPES) {
|
||||
addValueResources(file, resType, AndroidResourceUtil.getValueResourcesFromElement(resType.getName(), resources), myResources);
|
||||
}
|
||||
addValueResources(file, ResourceType.ATTR, resources.getAttrs(), myResources);
|
||||
addValueResources(file, ResourceType.DECLARE_STYLEABLE, resources.getDeclareStyleables(), myResources);
|
||||
}
|
||||
|
||||
for (final VirtualFile subdir : manager.getResourceSubdirs(null)) {
|
||||
final String subdirName = subdir.getName();
|
||||
final int index = subdirName.indexOf('-');
|
||||
final String typeName = index >= 0 ? subdirName.substring(0, index) : subdirName;
|
||||
final ResourceType type = ResourceType.getEnum(typeName);
|
||||
final boolean idProvidingResource = type != null && ArrayUtil.find(ResourceManager.ID_PROVIDING_RESOURCE_TYPES, type) >= 0;
|
||||
|
||||
FileIndexImplUtil.iterateRecursively(subdir, VirtualFileFilter.ALL, new ContentIterator() {
|
||||
@Override
|
||||
public boolean processFile(VirtualFile fileOrDir) {
|
||||
if (!fileOrDir.isDirectory()) {
|
||||
MyResourceFileData data = myResources.get(fileOrDir.getPath());
|
||||
if (data == null) {
|
||||
data = new MyResourceFileData();
|
||||
myResources.put(fileOrDir.getPath(), data);
|
||||
}
|
||||
|
||||
if (idProvidingResource) {
|
||||
data.setTimestamp(fileOrDir.getTimeStamp());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void addValueResources(VirtualFile file,
|
||||
ResourceType resType,
|
||||
Collection<? extends ResourceElement> resourceElements,
|
||||
Map<String, MyResourceFileData> result) {
|
||||
for (ResourceElement element : resourceElements) {
|
||||
final String name = element.getName().getValue();
|
||||
|
||||
if (name != null) {
|
||||
MyResourceFileData data = result.get(file.getPath());
|
||||
if (data == null) {
|
||||
data = new MyResourceFileData();
|
||||
result.put(file.getPath(), data);
|
||||
}
|
||||
data.addValueResource(new ResourceEntry(resType.getName(), name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ResourceNamesValidityState(@NotNull DataInput in) throws IOException {
|
||||
myAndroidTargetHashString = in.readUTF();
|
||||
myManifestTimestamp = in.readLong();
|
||||
|
||||
|
||||
final int resourcesCount = in.readInt();
|
||||
|
||||
|
||||
for (int i = 0; i < resourcesCount; i++) {
|
||||
final String type = in.readUTF();
|
||||
final String name = in.readUTF();
|
||||
myResourcesSet.add(new ResourceEntry(type, name));
|
||||
final String filePath = in.readUTF();
|
||||
|
||||
final int valueResourcesCount = in.readInt();
|
||||
final List<ResourceEntry> valueResources = new ArrayList<ResourceEntry>(valueResourcesCount);
|
||||
|
||||
for (int j = 0; j < valueResourcesCount; j++) {
|
||||
final String resType = in.readUTF();
|
||||
final String resName = in.readUTF();
|
||||
valueResources.add(new ResourceEntry(resType, resName));
|
||||
}
|
||||
final long fileTimestamp = in.readLong();
|
||||
myResources.put(filePath, new MyResourceFileData(valueResources, fileTimestamp));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,24 +135,86 @@ public class ResourceNamesValidityState implements ValidityState {
|
||||
if (!(otherState instanceof ResourceNamesValidityState)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
final ResourceNamesValidityState other = (ResourceNamesValidityState)otherState;
|
||||
|
||||
return other.myAndroidTargetHashString.equals(myAndroidTargetHashString) &&
|
||||
other.myManifestTimestamp == myManifestTimestamp &&
|
||||
other.myResourcesSet.equals(myResourcesSet);
|
||||
other.myResources.equals(myResources);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(DataOutput out) throws IOException {
|
||||
out.writeUTF(myAndroidTargetHashString);
|
||||
out.writeLong(myManifestTimestamp);
|
||||
|
||||
out.writeInt(myResourcesSet.size());
|
||||
|
||||
for (ResourceEntry resourceEntry : myResourcesSet) {
|
||||
out.writeUTF(resourceEntry.getType());
|
||||
out.writeUTF(resourceEntry.getName());
|
||||
|
||||
out.writeInt(myResources.size());
|
||||
|
||||
for (Map.Entry<String, MyResourceFileData> entry : myResources.entrySet()) {
|
||||
out.writeUTF(entry.getKey());
|
||||
|
||||
final MyResourceFileData data = entry.getValue();
|
||||
final List<ResourceEntry> valueResources = data.getValueResources();
|
||||
out.writeInt(valueResources.size());
|
||||
|
||||
for (ResourceEntry resource : valueResources) {
|
||||
out.writeUTF(resource.getType());
|
||||
out.writeUTF(resource.getName());
|
||||
}
|
||||
out.writeLong(data.getTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyResourceFileData {
|
||||
// order matters because of id assigning in R.java
|
||||
private final List<ResourceEntry> myValueResources;
|
||||
|
||||
private long myTimestamp;
|
||||
|
||||
MyResourceFileData() {
|
||||
this(new ArrayList<ResourceEntry>(), 0);
|
||||
}
|
||||
|
||||
private MyResourceFileData(@NotNull List<ResourceEntry> valueResources, long timestamp) {
|
||||
myValueResources = valueResources;
|
||||
myTimestamp = timestamp;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
List<ResourceEntry> getValueResources() {
|
||||
return myValueResources;
|
||||
}
|
||||
|
||||
long getTimestamp() {
|
||||
return myTimestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
myTimestamp = timestamp;
|
||||
}
|
||||
|
||||
public void addValueResource(@NotNull ResourceEntry entry) {
|
||||
myValueResources.add(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
MyResourceFileData data = (MyResourceFileData)o;
|
||||
|
||||
if (myTimestamp != data.myTimestamp) return false;
|
||||
if (!myValueResources.equals(data.myValueResources)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = myValueResources.hashCode();
|
||||
result = 31 * result + (int)(myTimestamp ^ (myTimestamp >>> 32));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -24,6 +24,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -96,7 +97,7 @@ public class LocalResourceManager extends ResourceManager {
|
||||
return AndroidRootUtil.getResourceDir(getFacet());
|
||||
}
|
||||
|
||||
public List<Resources> getResourceElements() {
|
||||
public List<Pair<Resources, VirtualFile>> getResourceElements() {
|
||||
return getResourceElements(null);
|
||||
}
|
||||
|
||||
@@ -200,7 +201,8 @@ public class LocalResourceManager extends ResourceManager {
|
||||
@NotNull
|
||||
public List<Attr> findAttrs(@NotNull String name) {
|
||||
List<Attr> list = new ArrayList<Attr>();
|
||||
for (Resources res : getResourceElements()) {
|
||||
for (Pair<Resources, VirtualFile> pair : getResourceElements()) {
|
||||
final Resources res = pair.getFirst();
|
||||
for (Attr attr : res.getAttrs()) {
|
||||
if (name.equals(attr.getName().getValue())) {
|
||||
list.add(attr);
|
||||
@@ -219,7 +221,8 @@ public class LocalResourceManager extends ResourceManager {
|
||||
|
||||
public List<DeclareStyleable> findStyleables(@NotNull String name) {
|
||||
List<DeclareStyleable> list = new ArrayList<DeclareStyleable>();
|
||||
for (Resources res : getResourceElements()) {
|
||||
for (Pair<Resources, VirtualFile> pair : getResourceElements()) {
|
||||
final Resources res = pair.getFirst();
|
||||
for (DeclareStyleable styleable : res.getDeclareStyleables()) {
|
||||
if (name.equals(styleable.getName().getValue())) {
|
||||
list.add(styleable);
|
||||
|
||||
@@ -17,11 +17,11 @@ package org.jetbrains.android.resourceManagers;
|
||||
|
||||
import com.android.resources.ResourceType;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
@@ -53,7 +53,9 @@ import static java.util.Collections.addAll;
|
||||
* @author coyote
|
||||
*/
|
||||
public abstract class ResourceManager {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.resourceManagers.LocalResourceManager");
|
||||
public static final ResourceType[] ID_PROVIDING_RESOURCE_TYPES = new ResourceType[] {
|
||||
ResourceType.LAYOUT, ResourceType.MENU
|
||||
};
|
||||
|
||||
protected final Module myModule;
|
||||
protected final AndroidFacet myFacet;
|
||||
@@ -130,17 +132,19 @@ public abstract class ResourceManager {
|
||||
return findResourceFiles(resType, null, true);
|
||||
}
|
||||
|
||||
protected List<Resources> getResourceElements(@Nullable Set<VirtualFile> files) {
|
||||
protected List<Pair<Resources, VirtualFile>> getResourceElements(@Nullable Set<VirtualFile> files) {
|
||||
return getRootDomElements(Resources.class, files);
|
||||
}
|
||||
|
||||
private <T extends DomElement> List<T> getRootDomElements(@NotNull Class<T> elementType,
|
||||
@Nullable Set<VirtualFile> files) {
|
||||
final List<T> result = new ArrayList<T>();
|
||||
private <T extends DomElement> List<Pair<T, VirtualFile>> getRootDomElements(@NotNull Class<T> elementType,
|
||||
@Nullable Set<VirtualFile> files) {
|
||||
final List<Pair<T, VirtualFile>> result = new ArrayList<Pair<T, VirtualFile>>();
|
||||
for (VirtualFile file : getAllValueResourceFiles()) {
|
||||
if ((files == null || files.contains(file)) && file.isValid()) {
|
||||
T element = AndroidUtils.loadDomElement(myModule, file, elementType);
|
||||
if (element != null) result.add(element);
|
||||
final T element = AndroidUtils.loadDomElement(myModule, file, elementType);
|
||||
if (element != null) {
|
||||
result.add(new Pair<T, VirtualFile>(element, file));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -162,8 +166,9 @@ public abstract class ResourceManager {
|
||||
|
||||
protected List<ResourceElement> getValueResources(@NotNull final String resourceType, @Nullable Set<VirtualFile> files) {
|
||||
final List<ResourceElement> result = new ArrayList<ResourceElement>();
|
||||
Collection<Resources> resourceFiles = getResourceElements(files);
|
||||
for (final Resources resources : resourceFiles) {
|
||||
List<Pair<Resources, VirtualFile>> resourceFiles = getResourceElements(files);
|
||||
for (final Pair<Resources, VirtualFile> pair : resourceFiles) {
|
||||
final Resources resources = pair.getFirst();
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -337,10 +342,11 @@ public abstract class ResourceManager {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<VirtualFile> getResourceSubdirsToSearchIds() {
|
||||
public List<VirtualFile> getResourceSubdirsToSearchIds() {
|
||||
final List<VirtualFile> resSubdirs = new ArrayList<VirtualFile>();
|
||||
resSubdirs.addAll(getResourceSubdirs(ResourceType.LAYOUT.getName()));
|
||||
resSubdirs.addAll(getResourceSubdirs(ResourceType.MENU.getName()));
|
||||
for (ResourceType type : ID_PROVIDING_RESOURCE_TYPES) {
|
||||
resSubdirs.addAll(getResourceSubdirs(type.getName()));
|
||||
}
|
||||
return resSubdirs;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
|
||||
import com.intellij.codeInspection.htmlInspections.RequiredAttributesInspection;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.command.undo.UndoManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
@@ -170,6 +171,12 @@ public class XmlTagInsertHandler implements InsertHandler<LookupElement> {
|
||||
if (myAttrValueMarker == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final UndoManager manager = UndoManager.getInstance(project);
|
||||
if (manager.isUndoInProgress() || manager.isRedoInProgress()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (chooseAttributeName) {
|
||||
final int startOffset = myAttrValueMarker.getStartOffset();
|
||||
final int endOffset = myAttrValueMarker.getEndOffset();
|
||||
|
||||
Reference in New Issue
Block a user