android augment: extend existing R class, because it can be used in maven resource processing mode

This commit is contained in:
Eugene Kudelevsky
2012-06-18 22:24:49 +04:00
parent 07586a4bee
commit 25ea7ac3e0
3 changed files with 74 additions and 25 deletions
@@ -1,5 +1,6 @@
package org.jetbrains.android.augment;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiType;
@@ -14,11 +15,11 @@ import org.jetbrains.annotations.Nullable;
* @author Eugene.Kudelevsky
*/
class AndroidLightField extends LightFieldBuilder {
private final AndroidLightClass myContext;
private final PsiClass myContext;
private final PsiType myType;
public AndroidLightField(@NotNull String name,
@NotNull AndroidLightClass context,
@NotNull PsiClass context,
@NotNull PsiType type) {
super(name, type, context);
myContext = context;
@@ -1,11 +1,14 @@
package org.jetbrains.android.augment;
import com.android.resources.ResourceType;
import com.intellij.openapi.project.DumbService;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiFile;
import com.intellij.psi.augment.PsiAugmentProvider;
import org.jetbrains.android.compiler.AndroidAptCompiler;
import com.intellij.psi.impl.source.PsiExtensibleClass;
import com.intellij.util.containers.HashSet;
import org.jetbrains.android.dom.converters.ResourceReferenceConverter;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.util.AndroidResourceUtil;
@@ -22,21 +25,16 @@ public class AndroidPsiAugmentProvider extends PsiAugmentProvider {
@NotNull
@Override
public <Psi extends PsiElement> List<Psi> getAugments(@NotNull PsiElement element, @NotNull Class<Psi> type) {
if (type != PsiClass.class ||
!(element instanceof PsiClass) ||
if ((type != PsiClass.class && type != PsiField.class) ||
!(element instanceof PsiExtensibleClass) ||
DumbService.isDumb(element.getProject())) {
return Collections.emptyList();
}
final PsiClass aClass = (PsiClass)element;
final PsiExtensibleClass aClass = (PsiExtensibleClass)element;
final String className = aClass.getName();
if (!AndroidUtils.R_CLASS_NAME.equals(className) &&
!AndroidUtils.MANIFEST_CLASS_NAME.equals(className)) {
return Collections.emptyList();
}
final AndroidFacet facet = AndroidFacet.getInstance(element);
if (facet == null || !AndroidAptCompiler.isToCompileModule(facet.getModule(), facet.getConfiguration())) {
if (facet == null) {
return Collections.emptyList();
}
@@ -45,20 +43,70 @@ public class AndroidPsiAugmentProvider extends PsiAugmentProvider {
return Collections.emptyList();
}
if (AndroidResourceUtil.isRJavaFile(facet, containingFile)) {
final Set<String> types = ResourceReferenceConverter.getResourceTypesInCurrentModule(facet);
final List<Psi> result = new ArrayList<Psi>(types.size());
if (type == PsiClass.class) {
if (AndroidUtils.R_CLASS_NAME.equals(className) &&
AndroidResourceUtil.isRJavaFile(facet, containingFile)) {
final Set<String> existingInnerClasses = getOwnInnerClasses(aClass);
final Set<String> types = ResourceReferenceConverter.getResourceTypesInCurrentModule(facet);
final List<Psi> result = new ArrayList<Psi>();
for (String resType : types) {
final AndroidLightClass resClass = new ResourceTypeClass(facet, resType, aClass);
result.add((Psi)resClass);
for (String resType : types) {
if (!existingInnerClasses.contains(resType)) {
final AndroidLightClass resClass = new ResourceTypeClass(facet, resType, aClass);
result.add((Psi)resClass);
}
}
return result;
}
else if (AndroidUtils.MANIFEST_CLASS_NAME.equals(className) &&
AndroidResourceUtil.isManifestJavaFile(facet, containingFile)) {
return Arrays.asList((Psi)new PermissionClass(facet, aClass),
(Psi)new PermissionGroupClass(facet, aClass));
}
return result;
}
else if (AndroidResourceUtil.isManifestJavaFile(facet, containingFile)) {
return Arrays.asList((Psi)new PermissionClass(facet, aClass),
(Psi)new PermissionGroupClass(facet, aClass));
else if (type == PsiField.class && !(aClass instanceof AndroidLightClass)) {
// extend existing inner classes, not provided by this augment (ex. they can be generated by maven)
final PsiClass parentClass = aClass.getContainingClass();
if (parentClass != null &&
AndroidUtils.R_CLASS_NAME.equals(parentClass.getName()) &&
AndroidResourceUtil.isRJavaFile(facet, containingFile)) {
final String resClassName = aClass.getName();
if (resClassName != null && ResourceType.getEnum(resClassName) != null) {
final Set<String> existingFields = getOwnFields(aClass);
final PsiField[] newFields = ResourceTypeClass.buildResourceFields(facet, resClassName, aClass);
final List<Psi> result = new ArrayList<Psi>();
for (PsiField field : newFields) {
if (!existingFields.contains(field.getName())) {
result.add((Psi)field);
}
}
return result;
}
}
}
return Collections.emptyList();
}
@NotNull
private static Set<String> getOwnInnerClasses(@NotNull PsiExtensibleClass aClass) {
final Set<String> result = new HashSet<String>();
for (PsiClass innerClass : aClass.getOwnInnerClasses()) {
result.add(innerClass.getName());
}
return result;
}
@NotNull
private static Set<String> getOwnFields(@NotNull PsiExtensibleClass aClass) {
final Set<String> result = new HashSet<String>();
for (PsiField field : aClass.getOwnFields()) {
result.add(field.getName());
}
return result;
}
}
@@ -40,9 +40,9 @@ class ResourceTypeClass extends AndroidLightClass {
}
@NotNull
private static PsiField[] buildResourceFields(@NotNull AndroidFacet facet,
@NotNull String resClassName,
@NotNull final AndroidLightClass context) {
static PsiField[] buildResourceFields(@NotNull AndroidFacet facet,
@NotNull String resClassName,
@NotNull final PsiClass context) {
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(facet.getModule().getProject());
final Collection<String> resNames = facet.getLocalResourceManager().getResourceNames(resClassName);
final PsiField[] result = new PsiField[resNames.size()];