From 25ea7ac3e0702e31010760351bdf27ef43675bbf Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Mon, 18 Jun 2012 22:08:50 +0400 Subject: [PATCH] android augment: extend existing R class, because it can be used in maven resource processing mode --- .../android/augment/AndroidLightField.java | 5 +- .../augment/AndroidPsiAugmentProvider.java | 88 ++++++++++++++----- .../android/augment/ResourceTypeClass.java | 6 +- 3 files changed, 74 insertions(+), 25 deletions(-) diff --git a/plugins/android/src/org/jetbrains/android/augment/AndroidLightField.java b/plugins/android/src/org/jetbrains/android/augment/AndroidLightField.java index dfb8d14d6bf4..bc8927520257 100644 --- a/plugins/android/src/org/jetbrains/android/augment/AndroidLightField.java +++ b/plugins/android/src/org/jetbrains/android/augment/AndroidLightField.java @@ -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; diff --git a/plugins/android/src/org/jetbrains/android/augment/AndroidPsiAugmentProvider.java b/plugins/android/src/org/jetbrains/android/augment/AndroidPsiAugmentProvider.java index 54a4cf1806c6..117713c57c0f 100644 --- a/plugins/android/src/org/jetbrains/android/augment/AndroidPsiAugmentProvider.java +++ b/plugins/android/src/org/jetbrains/android/augment/AndroidPsiAugmentProvider.java @@ -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 List getAugments(@NotNull PsiElement element, @NotNull Class 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 types = ResourceReferenceConverter.getResourceTypesInCurrentModule(facet); - final List result = new ArrayList(types.size()); + if (type == PsiClass.class) { + if (AndroidUtils.R_CLASS_NAME.equals(className) && + AndroidResourceUtil.isRJavaFile(facet, containingFile)) { + final Set existingInnerClasses = getOwnInnerClasses(aClass); + final Set types = ResourceReferenceConverter.getResourceTypesInCurrentModule(facet); + final List result = new ArrayList(); - 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 existingFields = getOwnFields(aClass); + final PsiField[] newFields = ResourceTypeClass.buildResourceFields(facet, resClassName, aClass); + final List result = new ArrayList(); + + for (PsiField field : newFields) { + if (!existingFields.contains(field.getName())) { + result.add((Psi)field); + } + } + return result; + } + } } return Collections.emptyList(); } + + @NotNull + private static Set getOwnInnerClasses(@NotNull PsiExtensibleClass aClass) { + final Set result = new HashSet(); + + for (PsiClass innerClass : aClass.getOwnInnerClasses()) { + result.add(innerClass.getName()); + } + return result; + } + + @NotNull + private static Set getOwnFields(@NotNull PsiExtensibleClass aClass) { + final Set result = new HashSet(); + + for (PsiField field : aClass.getOwnFields()) { + result.add(field.getName()); + } + return result; + } } diff --git a/plugins/android/src/org/jetbrains/android/augment/ResourceTypeClass.java b/plugins/android/src/org/jetbrains/android/augment/ResourceTypeClass.java index c05728a5e011..e4f1eda99bbf 100644 --- a/plugins/android/src/org/jetbrains/android/augment/ResourceTypeClass.java +++ b/plugins/android/src/org/jetbrains/android/augment/ResourceTypeClass.java @@ -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 resNames = facet.getLocalResourceManager().getResourceNames(resClassName); final PsiField[] result = new PsiField[resNames.size()];