diff --git a/plugins/android/src/org/jetbrains/android/augment/AndroidLightField.java b/plugins/android/src/org/jetbrains/android/augment/AndroidLightField.java index bc8927520257..c8b70c37cf8a 100644 --- a/plugins/android/src/org/jetbrains/android/augment/AndroidLightField.java +++ b/plugins/android/src/org/jetbrains/android/augment/AndroidLightField.java @@ -1,30 +1,48 @@ 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; +import com.intellij.psi.*; import com.intellij.psi.impl.PsiClassImplUtil; +import com.intellij.psi.impl.PsiVariableEx; import com.intellij.psi.impl.light.LightFieldBuilder; +import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + /** * @author Eugene.Kudelevsky */ -class AndroidLightField extends LightFieldBuilder { +class AndroidLightField extends LightFieldBuilder implements PsiVariableEx { private final PsiClass myContext; private final PsiType myType; + private final Object myConstantValue; + private final boolean myFinal; public AndroidLightField(@NotNull String name, @NotNull PsiClass context, - @NotNull PsiType type) { + @NotNull PsiType type, + boolean isFinal, + @Nullable Object constantValue) { super(name, type, context); myContext = context; myType = type; + myConstantValue = constantValue; + myFinal = isFinal; setContainingClass(context); + + final List modifiers = new ArrayList(); + modifiers.add(PsiModifier.PUBLIC); + modifiers.add(PsiModifier.STATIC); + + if (isFinal) { + modifiers.add(PsiModifier.FINAL); + } + setModifiers(ArrayUtil.toStringArray(modifiers)); } @Override @@ -40,6 +58,18 @@ class AndroidLightField extends LightFieldBuilder { @Override public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { - return new AndroidLightField(name, myContext, myType); + final AndroidLightField field = new AndroidLightField(name, myContext, myType, myFinal, myConstantValue); + field.setInitializer(getInitializer()); + return field; + } + + @Override + public Object computeConstantValue(Set visitedVars) { + return computeConstantValue(); + } + + @Override + public Object computeConstantValue() { + return myConstantValue; } } diff --git a/plugins/android/src/org/jetbrains/android/augment/ManifestInnerClass.java b/plugins/android/src/org/jetbrains/android/augment/ManifestInnerClass.java index fff6efd99239..3aaa8ae48311 100644 --- a/plugins/android/src/org/jetbrains/android/augment/ManifestInnerClass.java +++ b/plugins/android/src/org/jetbrains/android/augment/ManifestInnerClass.java @@ -44,8 +44,8 @@ abstract class ManifestInnerClass extends AndroidLightClass { final PsiElementFactory factory = JavaPsiFacade.getElementFactory(getProject()); int i = 0; for (Pair pair : pairs) { - final AndroidLightField field = new AndroidLightField(pair.getFirst(), ManifestInnerClass.this, stringType); - field.setModifiers(PsiModifier.PUBLIC, PsiModifier.STATIC); + final AndroidLightField field = + new AndroidLightField(pair.getFirst(), ManifestInnerClass.this, stringType, true, pair.getSecond()); field.setInitializer(factory.createExpressionFromText("\"" + pair.getSecond() + "\"", field)); result[i++] = field; } diff --git a/plugins/android/src/org/jetbrains/android/augment/ResourceTypeClass.java b/plugins/android/src/org/jetbrains/android/augment/ResourceTypeClass.java index e4f1eda99bbf..6f1959c706bb 100644 --- a/plugins/android/src/org/jetbrains/android/augment/ResourceTypeClass.java +++ b/plugins/android/src/org/jetbrains/android/augment/ResourceTypeClass.java @@ -1,11 +1,13 @@ package org.jetbrains.android.augment; import com.android.resources.ResourceType; +import com.intellij.openapi.module.Module; import com.intellij.psi.*; import com.intellij.psi.util.CachedValue; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; +import org.jetbrains.android.compiler.AndroidCompileUtil; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.annotations.NotNull; @@ -43,6 +45,9 @@ class ResourceTypeClass extends AndroidLightClass { static PsiField[] buildResourceFields(@NotNull AndroidFacet facet, @NotNull String resClassName, @NotNull final PsiClass context) { + final Module circularDepLibWithSamePackage = AndroidCompileUtil.findCircularDependencyOnLibraryWithSamePackage(facet); + final boolean generateNonFinalFields = facet.getConfiguration().LIBRARY_PROJECT || circularDepLibWithSamePackage != null; + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(facet.getModule().getProject()); final Collection resNames = facet.getLocalResourceManager().getResourceNames(resClassName); final PsiField[] result = new PsiField[resNames.size()]; @@ -51,8 +56,8 @@ class ResourceTypeClass extends AndroidLightClass { final PsiType type = ResourceType.STYLEABLE.getName().equals(resClassName) ? PsiType.INT.createArrayType() : PsiType.INT; - final AndroidLightField field = new AndroidLightField(AndroidResourceUtil.getFieldNameByResourceName(resName), context, type); - field.setModifiers(PsiModifier.PUBLIC, PsiModifier.STATIC); + final AndroidLightField field = new AndroidLightField(AndroidResourceUtil.getFieldNameByResourceName(resName), context, + type, !generateNonFinalFields, generateNonFinalFields ? null : 0); field.setInitializer(factory.createExpressionFromText("0", field)); result[i++] = field; } diff --git a/plugins/android/testData/dom/resources/JavaHighlighting.java b/plugins/android/testData/dom/resources/JavaHighlighting.java index 79b8b63d961e..967ff91ece11 100644 --- a/plugins/android/testData/dom/resources/JavaHighlighting.java +++ b/plugins/android/testData/dom/resources/JavaHighlighting.java @@ -1,5 +1,7 @@ package p1.p2; +import java.lang.System; + public class JavaCompletion1 { public void f() { int n1 = R.string.my_string; @@ -9,5 +11,13 @@ public class JavaCompletion1 { int n5 = R.attr.myAttr1; n5 = R.attr.myAttr2; n5 = R.attr.android_text; + + switch(n1) { + case R.string.my_string: + System.out.println("abacaba"); + break; + default: + break; + } } } \ No newline at end of file diff --git a/plugins/android/testData/libModule/JavaHighlighting.java b/plugins/android/testData/libModule/JavaHighlighting.java new file mode 100644 index 000000000000..0705009aa81e --- /dev/null +++ b/plugins/android/testData/libModule/JavaHighlighting.java @@ -0,0 +1,16 @@ +package p1.p2.lib; + +import java.lang.System; + +public class JavaHighlighting { + public void f(int n) { + int m = R.string.myLibResource; + switch(n) { + case R.string.myLibResource: + System.out.println("aba"); + break; + default: + break; + } + } +} \ No newline at end of file diff --git a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLibraryProjectTest.java b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLibraryProjectTest.java index 6207725f35da..e4b926385c6f 100644 --- a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLibraryProjectTest.java +++ b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidLibraryProjectTest.java @@ -141,6 +141,16 @@ public class AndroidLibraryProjectTest extends UsefulTestCase { myFixture.checkHighlighting(true, true, true); } + public void testJavaHighlighting() { + createInitialStructure(); + myFixture.copyFileToProject(BASE_PATH + "FindUsagesR1.java", "lib/src/p1/p2/lib/R.java"); + String to = "lib/src/p1/p2/lib" + getTestName(true) + ".java"; + VirtualFile file = myFixture.copyFileToProject(BASE_PATH + getTestName(false) + ".java", to); + myFixture.configureFromExistingVirtualFile(file); + myFixture.doHighlighting(); + myFixture.checkHighlighting(true, true, true); + } + private void doRename(final VirtualFile file, final String newName) { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override