mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
android dependency processor: search for refs to R class instead of usages of each constant field (inside project they may be non-existent or non-up-to date)
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.compiler;
|
||||
|
||||
import com.intellij.compiler.make.CacheCorruptedException;
|
||||
import com.intellij.compiler.make.CachingSearcher;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
|
||||
@@ -25,5 +27,5 @@ import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
public interface DependencyProcessor {
|
||||
ExtensionPointName<DependencyProcessor> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.makeDependencyProcessor");
|
||||
|
||||
void processDependencies(CompileContext context, int classQualifiedName);
|
||||
void processDependencies(CompileContext context, int classQualifiedName, CachingSearcher searcher) throws CacheCorruptedException;
|
||||
}
|
||||
|
||||
@@ -429,7 +429,7 @@ public class DependencyCache {
|
||||
}
|
||||
changedRetentionPolicyDependencyProcessor.checkAnnotationRetentionPolicyChanges(qName);
|
||||
for (DependencyProcessor additionalProcessor : DependencyProcessor.EXTENSION_POINT_NAME.getExtensions()) {
|
||||
additionalProcessor.processDependencies(context, qName);
|
||||
additionalProcessor.processDependencies(context, qName, searcher);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -61,7 +61,7 @@ public class AndroidCommonUtils {
|
||||
private static final Pattern ERROR_PATTERN = Pattern.compile(".*error.*");
|
||||
private static final Pattern EXCEPTION_PATTERN = Pattern.compile(".*exception.*");
|
||||
|
||||
private static final Pattern R_PATTERN = Pattern.compile("R(\\$.*)?\\.class");
|
||||
public static final Pattern R_PATTERN = Pattern.compile("R(\\$.*)?\\.class");
|
||||
private static final Pattern MANIFEST_PATTERN = Pattern.compile("Manifest(\\$.*)?\\.class");
|
||||
private static final String BUILD_CONFIG_CLASS_NAME = "BuildConfig.class";
|
||||
|
||||
|
||||
@@ -143,6 +143,7 @@
|
||||
<compiler implementation="org.jetbrains.android.compiler.AndroidPngFilesCachingCompiler"/>
|
||||
<compiler implementation="org.jetbrains.android.compiler.AndroidResourcesPackagingCompiler"/>
|
||||
<compiler implementation="org.jetbrains.android.compiler.AndroidPackagingCompiler"/>
|
||||
<compiler.makeDependencyProcessor implementation="org.jetbrains.android.compiler.AndroidDependencyProcessor"/>
|
||||
|
||||
<completion.contributor language="XML" implementationClass="org.jetbrains.android.AndroidCompletionContributor"
|
||||
id="compositieAttributeValues" order="first"/>
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.jetbrains.android.compiler;
|
||||
|
||||
import com.intellij.compiler.DependencyProcessor;
|
||||
import com.intellij.compiler.make.*;
|
||||
import com.intellij.facet.ProjectFacetManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.ex.CompileContextEx;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.util.AndroidCommonUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Eugene.Kudelevsky
|
||||
*/
|
||||
public class AndroidDependencyProcessor implements DependencyProcessor {
|
||||
@Override
|
||||
public void processDependencies(final CompileContext context, int classQualifiedName, final CachingSearcher searcher)
|
||||
throws CacheCorruptedException {
|
||||
if (!(context instanceof CompileContextEx)) {
|
||||
return;
|
||||
}
|
||||
final Project project = context.getProject();
|
||||
|
||||
if (!ProjectFacetManager.getInstance(project).hasFacets(AndroidFacet.ID)) {
|
||||
return;
|
||||
}
|
||||
final DependencyCache depCache = ((CompileContextEx)context).getDependencyCache();
|
||||
final Cache cache = depCache.getCache();
|
||||
final String path = cache.getPath(classQualifiedName);
|
||||
final String classFileName = new File(path).getName();
|
||||
|
||||
if (!AndroidCommonUtils.R_PATTERN.matcher(classFileName).matches()) {
|
||||
return;
|
||||
}
|
||||
final String qName = depCache.resolve(classQualifiedName);
|
||||
final int idx = qName.indexOf('$');
|
||||
final String topLevelClassName = idx < 0 ? qName : qName.substring(0, idx);
|
||||
final Set<String> qNamesToMark = new HashSet<String>();
|
||||
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final PsiClass[] classes =
|
||||
JavaPsiFacade.getInstance(project).findClasses(topLevelClassName, GlobalSearchScope.allScope(project));
|
||||
|
||||
for (PsiClass aClass : classes) {
|
||||
final Collection<PsiReference> references = searcher.findReferences(aClass, true);
|
||||
|
||||
for (PsiReference reference : references) {
|
||||
final PsiClass ownerClass = getOwnerClass(reference.getElement());
|
||||
if (ownerClass != null && !ownerClass.equals(aClass)) {
|
||||
final String ownerClassQName = ownerClass.getQualifiedName();
|
||||
|
||||
if (ownerClassQName != null) {
|
||||
qNamesToMark.add(ownerClassQName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (String toMark : qNamesToMark) {
|
||||
final int qualifiedName = depCache.getSymbolTable().getId(toMark);
|
||||
depCache.markClass(qualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass getOwnerClass(PsiElement element) {
|
||||
while (!(element instanceof PsiFile)) {
|
||||
if (element instanceof PsiClass && element.getParent() instanceof PsiJavaFile) {
|
||||
return (PsiClass)element;
|
||||
}
|
||||
element = element.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user