augment of R and Manifest classes, do not generate the constants anymore

This commit is contained in:
Eugene Kudelevsky
2012-06-18 17:27:09 +04:00
parent 332b692e1f
commit 7c7ba0359e
50 changed files with 1017 additions and 213 deletions
+1
View File
@@ -220,6 +220,7 @@
<renameHandler implementation="org.jetbrains.android.AndroidRenameHandler" order="first"/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.android.inspections.AndroidQuickFixProvider"/>
<lang.psiAugmentProvider implementation="org.jetbrains.android.augment.AndroidPsiAugmentProvider"/>
<packaging.elementType implementation="org.jetbrains.android.compiler.artifact.AndroidFinalPackageElementType"/>
<packaging.sourceItemProvider implementation="org.jetbrains.android.compiler.artifact.AndroidSourceItemsProvider"/>
@@ -0,0 +1,338 @@
package org.jetbrains.android.augment;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.ItemPresentationProviders;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiClassImplUtil;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.light.LightElement;
import com.intellij.psi.impl.light.LightEmptyImplementsList;
import com.intellij.psi.impl.light.LightModifierList;
import com.intellij.psi.impl.light.LightTypeParameterListBuilder;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.SearchScope;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author Eugene.Kudelevsky
*/
public abstract class AndroidLightClass extends LightElement implements PsiClass, SyntheticElement {
private final PsiClass myContainingClass;
protected final String myName;
protected AndroidLightClass(@NotNull PsiClass context, @NotNull String name) {
super(context.getManager(), JavaLanguage.INSTANCE);
myContainingClass = context;
myName = name;
}
@Override
public String toString() {
return "AndroidRClass";
}
@Override
public String getQualifiedName() {
return myContainingClass.getQualifiedName() + '.' + myName;
}
@Override
public boolean isInterface() {
return false;
}
@Override
public boolean isAnnotationType() {
return false;
}
@Override
public boolean isEnum() {
return false;
}
@Override
public PsiReferenceList getExtendsList() {
return new LightEmptyImplementsList(myManager);
}
@Override
public PsiReferenceList getImplementsList() {
return new LightEmptyImplementsList(myManager);
}
@NotNull
@Override
public PsiClassType[] getExtendsListTypes() {
return PsiClassType.EMPTY_ARRAY;
}
@NotNull
@Override
public PsiClassType[] getImplementsListTypes() {
return PsiClassType.EMPTY_ARRAY;
}
@Override
public PsiClass getSuperClass() {
return null;
}
@Override
public PsiClass[] getInterfaces() {
return PsiClass.EMPTY_ARRAY;
}
@NotNull
@Override
public PsiClass[] getSupers() {
return PsiClass.EMPTY_ARRAY;
}
@NotNull
@Override
public PsiClassType[] getSuperTypes() {
return PsiClassType.EMPTY_ARRAY;
}
@NotNull
@Override
public abstract PsiField[] getFields();
@NotNull
@Override
public PsiMethod[] getMethods() {
return PsiMethod.EMPTY_ARRAY;
}
@NotNull
@Override
public PsiMethod[] getConstructors() {
return PsiMethod.EMPTY_ARRAY;
}
@NotNull
@Override
public PsiClass[] getInnerClasses() {
return PsiClass.EMPTY_ARRAY;
}
@NotNull
@Override
public PsiClassInitializer[] getInitializers() {
return PsiClassInitializer.EMPTY_ARRAY;
}
@NotNull
@Override
public PsiField[] getAllFields() {
return getFields();
}
@NotNull
@Override
public PsiMethod[] getAllMethods() {
return PsiMethod.EMPTY_ARRAY;
}
@NotNull
@Override
public PsiClass[] getAllInnerClasses() {
return PsiClass.EMPTY_ARRAY;
}
@Override
public PsiField findFieldByName(@NonNls String name, boolean checkBases) {
final PsiField[] fields = getFields();
for (final PsiField field : fields) {
if (name.equals(field.getName())) return field;
}
return null;
}
@Override
public PsiMethod findMethodBySignature(PsiMethod patternMethod, boolean checkBases) {
return null;
}
@NotNull
@Override
public PsiMethod[] findMethodsBySignature(PsiMethod patternMethod, boolean checkBases) {
return PsiMethod.EMPTY_ARRAY;
}
@NotNull
@Override
public PsiMethod[] findMethodsByName(@NonNls String name, boolean checkBases) {
return PsiMethod.EMPTY_ARRAY;
}
@NotNull
@Override
public List<Pair<PsiMethod, PsiSubstitutor>> findMethodsAndTheirSubstitutorsByName(@NonNls String name, boolean checkBases) {
return Collections.emptyList();
}
@NotNull
@Override
public List<Pair<PsiMethod, PsiSubstitutor>> getAllMethodsAndTheirSubstitutors() {
return Collections.emptyList();
}
@Override
public PsiClass findInnerClassByName(@NonNls String name, boolean checkBases) {
return null;
}
@Override
public PsiElement getLBrace() {
return null;
}
@Override
public PsiElement getRBrace() {
return null;
}
@Override
public PsiIdentifier getNameIdentifier() {
return null;
}
@NotNull
@Override
public PsiElement getNavigationElement() {
return myContainingClass;
}
@Nullable
@Override
public PsiElement getScope() {
return null;
}
@Override
public boolean isInheritor(@NotNull PsiClass baseClass, boolean checkDeep) {
return false;
}
@Override
public boolean isInheritorDeep(PsiClass baseClass, @Nullable PsiClass classToByPass) {
return false;
}
@Override
public PsiClass getContainingClass() {
return myContainingClass;
}
@NotNull
@Override
public Collection<HierarchicalMethodSignature> getVisibleSignatures() {
return Collections.emptyList();
}
@Override
public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
throw new IncorrectOperationException("Cannot change the name of " + getQualifiedName() + " class");
}
@Override
public PsiDocComment getDocComment() {
return null;
}
@Override
public boolean isDeprecated() {
return false;
}
@Override
public boolean hasTypeParameters() {
return false;
}
@Override
public PsiTypeParameterList getTypeParameterList() {
return new LightTypeParameterListBuilder(myManager, getLanguage());
}
@NotNull
@Override
public PsiTypeParameter[] getTypeParameters() {
return PsiTypeParameter.EMPTY_ARRAY;
}
@Override
public PsiModifierList getModifierList() {
return new LightModifierList(myManager, getLanguage(), PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL);
}
@Override
public boolean hasModifierProperty(@PsiModifier.ModifierConstant @NonNls @NotNull String name) {
final PsiModifierList list = getModifierList();
return list != null && list.hasModifierProperty(name);
}
@Override
public String getName() {
return myName;
}
@Override
protected boolean isVisibilitySupported() {
return true;
}
@Override
protected Icon getElementIcon(@IconFlags int flags) {
return PsiClassImplUtil.getClassIcon(flags, this);
}
@Override
public boolean isEquivalentTo(PsiElement another) {
return PsiClassImplUtil.isClassEquivalentTo(this, another);
}
@NotNull
@Override
public SearchScope getUseScope() {
return PsiImplUtil.getMemberUseScope(this);
}
@Override
public ItemPresentation getPresentation() {
return ItemPresentationProviders.getItemPresentation(this);
}
@Nullable
@Override
public PsiFile getContainingFile() {
final PsiClass containingClass = getContainingClass();
return containingClass == null ? null : containingClass.getContainingFile();
}
@Override
public PsiElement getParent() {
return myContainingClass;
}
@Override
public boolean processDeclarations(@NotNull final PsiScopeProcessor processor,
@NotNull final ResolveState state,
final PsiElement lastParent,
@NotNull final PsiElement place) {
return PsiClassImplUtil.processDeclarationsInClass(this, processor, state, null, lastParent, place, false);
}
}
@@ -0,0 +1,28 @@
package org.jetbrains.android.augment;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiType;
import com.intellij.psi.impl.light.LightFieldBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Eugene.Kudelevsky
*/
class AndroidLightField extends LightFieldBuilder {
private final AndroidLightClass myContext;
public AndroidLightField(@NotNull String name,
@NotNull AndroidLightClass context,
@NotNull PsiType type) {
super(name, type, context);
myContext = context;
setContainingClass(context);
}
@Nullable
@Override
public PsiFile getContainingFile() {
return myContext.getContainingFile();
}
}
@@ -0,0 +1,61 @@
package org.jetbrains.android.augment;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.augment.PsiAugmentProvider;
import org.jetbrains.android.dom.converters.ResourceReferenceConverter;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.util.AndroidResourceUtil;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NotNull;
import java.util.*;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidPsiAugmentProvider extends PsiAugmentProvider {
@SuppressWarnings("unchecked")
@NotNull
@Override
public <Psi extends PsiElement> List<Psi> getAugments(@NotNull PsiElement element, @NotNull Class<Psi> type) {
if (type != PsiClass.class ||
!(element instanceof PsiClass)) {
return Collections.emptyList();
}
final PsiClass aClass = (PsiClass)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) {
return Collections.emptyList();
}
final PsiFile containingFile = element.getContainingFile();
if (containingFile == null) {
return Collections.emptyList();
}
if (AndroidResourceUtil.isRJavaFile(facet, containingFile)) {
final Set<String> types = ResourceReferenceConverter.getResourceTypesInCurrentModule(facet);
final List<Psi> result = new ArrayList<Psi>(types.size());
for (String resType : types) {
final AndroidLightClass resClass = new ResourceTypeClass(facet, resType, aClass);
result.add((Psi)resClass);
}
return result;
}
else if (AndroidResourceUtil.isManifestJavaFile(facet, containingFile)) {
return Arrays.asList((Psi)new PermissionClass(facet, aClass),
(Psi)new PermissionGroupClass(facet, aClass));
}
return Collections.emptyList();
}
}
@@ -0,0 +1,64 @@
package org.jetbrains.android.augment;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
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 com.intellij.psi.xml.XmlElement;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author Eugene.Kudelevsky
*/
abstract class ManifestInnerClass extends AndroidLightClass {
private CachedValue<PsiField[]> myFieldsCache;
private final AndroidFacet myFacet;
ManifestInnerClass(@NotNull AndroidFacet facet, @NotNull String name, @NotNull PsiClass context) {
super(context, name);
myFacet = facet;
}
@NotNull
@Override
public PsiField[] getFields() {
if (myFieldsCache == null) {
myFieldsCache = CachedValuesManager.getManager(getProject()).createCachedValue(new CachedValueProvider<PsiField[]>() {
@Override
public Result<PsiField[]> compute() {
final Manifest manifest = myFacet.getManifest();
if (manifest == null) {
return Result.create(PsiField.EMPTY_ARRAY, PsiModificationTracker.MODIFICATION_COUNT);
}
final List<Pair<String, String>> pairs = doGetFields(manifest);
final PsiField[] result = new PsiField[pairs.size()];
final PsiClassType stringType = PsiType.getJavaLangString(myManager, GlobalSearchScope.allScope(getProject()));
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(getProject());
int i = 0;
for (Pair<String, String> pair : pairs) {
final AndroidLightField field = new AndroidLightField(pair.getFirst(), ManifestInnerClass.this, stringType);
field.setModifiers(PsiModifier.PUBLIC, PsiModifier.STATIC);
field.setInitializer(factory.createExpressionFromText("\"" + pair.getSecond() + "\"", field));
result[i++] = field;
}
final XmlElement xmlElement = manifest.getXmlElement();
final PsiFile psiManifestFile = xmlElement != null ? xmlElement.getContainingFile() : null;
return Result.create(result, psiManifestFile != null ? psiManifestFile : PsiModificationTracker.MODIFICATION_COUNT);
}
});
}
return myFieldsCache.getValue();
}
@NotNull
protected abstract List<Pair<String, String>> doGetFields(@NotNull Manifest manifest);
}
@@ -0,0 +1,41 @@
package org.jetbrains.android.augment;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiClass;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.dom.manifest.Permission;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.util.AndroidResourceUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author Eugene.Kudelevsky
*/
class PermissionClass extends ManifestInnerClass {
PermissionClass(@NotNull AndroidFacet facet, @NotNull PsiClass context) {
super(facet, "permission", context);
}
@NotNull
@Override
protected List<Pair<String, String>> doGetFields(@NotNull Manifest manifest) {
final List<Pair<String, String>> result = new ArrayList<Pair<String, String>>();
for (Permission permission : manifest.getPermissions()) {
final String name = permission.getName().getValue();
if (name != null && name.length() > 0) {
final int lastDotIndex = name.lastIndexOf('.');
final String lastId = name.substring(lastDotIndex + 1);
if (lastId.length() > 0) {
result.add(Pair.create(AndroidResourceUtil.getFieldNameByResourceName(lastId), name));
}
}
}
return result;
}
}
@@ -0,0 +1,41 @@
package org.jetbrains.android.augment;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiClass;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.dom.manifest.PermissionGroup;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.util.AndroidResourceUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* @author Eugene.Kudelevsky
*/
public class PermissionGroupClass extends ManifestInnerClass {
PermissionGroupClass(@NotNull AndroidFacet facet, @NotNull PsiClass context) {
super(facet, "permission_group", context);
}
@NotNull
@Override
protected List<Pair<String, String>> doGetFields(@NotNull Manifest manifest) {
final List<Pair<String, String>> result = new ArrayList<Pair<String, String>>();
for (PermissionGroup permissionGroup : manifest.getPermissionGroups()) {
final String name = permissionGroup.getName().getValue();
if (name != null && name.length() > 0) {
final int lastDotIndex = name.lastIndexOf('.');
final String lastId = name.substring(lastDotIndex + 1);
if (lastId.length() > 0) {
result.add(Pair.create(AndroidResourceUtil.getFieldNameByResourceName(lastId), name));
}
}
}
return result;
}
}
@@ -0,0 +1,57 @@
package org.jetbrains.android.augment;
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.facet.AndroidFacet;
import org.jetbrains.android.util.AndroidResourceUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* @author Eugene.Kudelevsky
*/
class ResourceTypeClass extends AndroidLightClass {
private CachedValue<PsiField[]> myFieldsCache;
private final AndroidFacet myFacet;
public ResourceTypeClass(@NotNull AndroidFacet facet, @NotNull String name, @NotNull PsiClass context) {
super(context, name);
myFacet = facet;
}
@NotNull
@Override
public PsiField[] getFields() {
if (myFieldsCache == null) {
myFieldsCache = CachedValuesManager.getManager(getProject()).createCachedValue(new CachedValueProvider<PsiField[]>() {
@Override
public Result<PsiField[]> compute() {
final PsiField[] fields = buildResourceFields(myFacet, myName, ResourceTypeClass.this);
return Result.create(fields, PsiModificationTracker.MODIFICATION_COUNT);
}
});
}
return myFieldsCache.getValue();
}
@NotNull
private static PsiField[] buildResourceFields(@NotNull AndroidFacet facet,
@NotNull String resType,
@NotNull final AndroidLightClass context) {
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(facet.getModule().getProject());
final Collection<String> resNames = facet.getLocalResourceManager().getResourceNames(resType);
final PsiField[] result = new PsiField[resNames.size()];
int i = 0;
for (String resName : resNames) {
final AndroidLightField field = new AndroidLightField(AndroidResourceUtil.getFieldNameByResourceName(resName), context, PsiType.INT);
field.setModifiers(PsiModifier.PUBLIC, PsiModifier.STATIC);
field.setInitializer(factory.createExpressionFromText("0", field));
result[i++] = field;
}
return result;
}
}
@@ -19,10 +19,8 @@ import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import org.jetbrains.android.compiler.tools.AndroidApt;
import org.jetbrains.android.compiler.tools.AndroidIdl;
import org.jetbrains.android.compiler.tools.AndroidRenderscript;
import org.jetbrains.android.dom.manifest.Manifest;
@@ -33,12 +31,13 @@ import org.jetbrains.android.fileTypes.AndroidRenderscriptFileType;
import org.jetbrains.android.sdk.AndroidPlatform;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidCompilerMessageKind;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
@@ -283,36 +282,33 @@ public class AndroidAutogenerator {
// Aapt generation can be very long, so we generate it in temp directory first
tempOutDir = FileUtil.createTempDirectory("android_apt_autogeneration", "tmp");
final Map<AndroidCompilerMessageKind, List<String>> messages =
AndroidApt.compile(item.myTarget, item.myPlatformToolsRevision, item.myManifestFileOsPath, item.myPackage,
tempOutDir.getPath(), item.myResDirOsPaths, ArrayUtil.EMPTY_STRING_ARRAY, item.myNonConstantFields);
generateStubClasses(item.myPackage, tempOutDir,
AndroidUtils.R_CLASS_NAME,
AndroidUtils.MANIFEST_CLASS_NAME);
if (messages.get(AndroidCompilerMessageKind.ERROR).size() == 0) {
for (String genFileRelPath : item.myGenFileRelPath2package.keySet()) {
final File srcFile = new File(tempOutDir.getPath() + '/' + genFileRelPath);
for (String genFileRelPath : item.myGenFileRelPath2package.keySet()) {
final File srcFile = new File(tempOutDir.getPath() + '/' + genFileRelPath);
if (srcFile.isFile()) {
final File dstFile = new File(item.myOutputDirOsPath + '/' + genFileRelPath);
if (srcFile.isFile()) {
final File dstFile = new File(item.myOutputDirOsPath + '/' + genFileRelPath);
if (dstFile.exists()) {
if (!FileUtil.delete(dstFile)) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
if (module.isDisposed() || module.getProject().isDisposed()) {
return;
}
context.addMessage(CompilerMessageCategory.ERROR,
"Cannot delete " + FileUtil.toSystemDependentName(dstFile.getPath()), null, -1, -1);
if (dstFile.exists()) {
if (!FileUtil.delete(dstFile)) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
if (module.isDisposed() || module.getProject().isDisposed()) {
return;
}
});
}
context.addMessage(CompilerMessageCategory.ERROR,
"Cannot delete " + FileUtil.toSystemDependentName(dstFile.getPath()), null, -1, -1);
}
});
}
FileUtil.rename(srcFile, dstFile);
}
FileUtil.rename(srcFile, dstFile);
}
}
AndroidCompileUtil.addMessages(context, AndroidCompileUtil.toCompilerMessageCategoryKeys(messages), module);
for (Map.Entry<String, String> entry : item.myGenFileRelPath2package.entrySet()) {
final String path = item.myOutputDirOsPath + '/' + entry.getKey();
@@ -328,16 +324,13 @@ public class AndroidAutogenerator {
if (genSourceRoot != null) {
genSourceRoot.refresh(false, true);
}
facet.clearAutogeneratedFiles(AndroidAutogeneratorMode.AAPT);
if (messages.get(AndroidCompilerMessageKind.ERROR).size() == 0) {
facet.clearAutogeneratedFiles(AndroidAutogeneratorMode.AAPT);
for (String relPath : item.myGenFileRelPath2package.keySet()) {
final VirtualFile genFile = LocalFileSystem.getInstance().findFileByPath(item.myOutputDirOsPath + '/' + relPath);
for (String relPath : item.myGenFileRelPath2package.keySet()) {
final VirtualFile genFile = LocalFileSystem.getInstance().findFileByPath(item.myOutputDirOsPath + '/' + relPath);
if (genFile != null && genFile.exists()) {
facet.markFileAutogenerated(AndroidAutogeneratorMode.AAPT, genFile);
}
if (genFile != null && genFile.exists()) {
facet.markFileAutogenerated(AndroidAutogeneratorMode.AAPT, genFile);
}
}
}
@@ -357,6 +350,30 @@ public class AndroidAutogenerator {
}
}
private static void generateStubClasses(@NotNull String aPackage, @NotNull File outputDir, @NotNull String... classNames)
throws IOException {
assert aPackage.length() > 0;
for (String className : classNames) {
final File packageDir = new File(outputDir.getPath() + '/' + aPackage.replace('.', '/'));
if (!packageDir.exists() && !packageDir.mkdirs()) {
throw new IOException("Cannot create directory " + FileUtil.toSystemDependentName(packageDir.getPath()));
}
final BufferedWriter writer = new BufferedWriter(new FileWriter(new File(packageDir, className + ".java")));
try {
writer.write(
"package " + aPackage + ";\n\n" +
"/* This stub is for using by IDE only. It is NOT the " + className + " class actually packed into APK */\n" +
"public final class " + className + " {\n" +
"}"
);
}
finally {
writer.close();
}
}
}
private static void removeAllFilesWithSameName(@NotNull final Module module, @NotNull File file, @NotNull String directoryPath) {
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(file);
final VirtualFile genDir = LocalFileSystem.getInstance().findFileByPath(directoryPath);
@@ -15,7 +15,6 @@
*/
package org.jetbrains.android.compiler;
import com.android.resources.ResourceType;
import com.intellij.CommonBundle;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.CompilerConfigurationImpl;
@@ -35,7 +34,6 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.ui.Messages;
@@ -57,18 +55,16 @@ import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import org.jetbrains.android.compiler.artifact.*;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.dom.resources.Attr;
import org.jetbrains.android.dom.resources.DeclareStyleable;
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.AndroidFacetConfiguration;
import org.jetbrains.android.facet.AndroidRootUtil;
import org.jetbrains.android.fileTypes.AndroidIdlFileType;
import org.jetbrains.android.fileTypes.AndroidRenderscriptFileType;
import org.jetbrains.android.resourceManagers.LocalResourceManager;
import org.jetbrains.android.sdk.AndroidPlatform;
import org.jetbrains.android.util.*;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidCompilerMessageKind;
import org.jetbrains.android.util.AndroidExecutionUtil;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -140,18 +136,6 @@ public class AndroidCompileUtil {
addMessages(context, messages, null, module);
}
public static void addMessages(@NotNull Map<CompilerMessageCategory, List<String>> messages,
@NotNull Map<CompilerMessageCategory, List<String>> toAdd) {
for (Map.Entry<CompilerMessageCategory, List<String>> entry : toAdd.entrySet()) {
List<String> list = messages.get(entry.getKey());
if (list == null) {
list = new ArrayList<String>();
messages.put(entry.getKey(), list);
}
list.addAll(entry.getValue());
}
}
static void addMessages(final CompileContext context,
final Map<CompilerMessageCategory, List<String>> messages,
@Nullable final Map<VirtualFile, VirtualFile> presentableFilesMap,
@@ -711,95 +695,6 @@ public class AndroidCompileUtil {
}
}
public static void collectAllResources(@NotNull final AndroidFacet facet, final Set<ResourceEntry> resourceSet) {
final LocalResourceManager manager = facet.getLocalResourceManager();
final Project project = facet.getModule().getProject();
for (final ResourceType resType : AndroidResourceUtil.VALUE_RESOURCE_TYPES) {
for (final ResourceElement element : manager.getValueResources(resType.getName())) {
waitForSmartMode(project);
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
if (!element.isValid() || facet.getModule().isDisposed() || project.isDisposed()) {
return;
}
final String name = element.getName().getValue();
if (name != null) {
resourceSet.add(new ResourceEntry(resType.getName(), name));
}
}
});
}
}
for (final Pair<Resources, VirtualFile> pair : manager.getResourceElements()) {
final Resources resources = pair.getFirst();
waitForSmartMode(project);
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
if (!resources.isValid() || facet.getModule().isDisposed() || project.isDisposed()) {
return;
}
for (final Attr attr : resources.getAttrs()) {
final String name = attr.getName().getValue();
if (name != null) {
resourceSet.add(new ResourceEntry(ResourceType.ATTR.getName(), name));
}
}
for (final DeclareStyleable styleable : resources.getDeclareStyleables()) {
final String name = styleable.getName().getValue();
if (name != null) {
resourceSet.add(new ResourceEntry(ResourceType.DECLARE_STYLEABLE.getName(), name));
}
}
}
});
}
waitForSmartMode(project);
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
public void run() {
if (facet.getModule().isDisposed() || project.isDisposed()) {
return;
}
for (String id : manager.getIds()) {
resourceSet.add(new ResourceEntry(ResourceType.ID.getName(), id));
}
}
});
final HashSet<VirtualFile> visited = new HashSet<VirtualFile>();
for (VirtualFile subdir : manager.getResourceSubdirs(null)) {
final HashSet<VirtualFile> resourceFiles = new HashSet<VirtualFile>();
AndroidUtils.collectFiles(subdir, visited, resourceFiles);
for (VirtualFile file : resourceFiles) {
final String subdirName = subdir.getName();
final int index = subdirName.indexOf('-');
final String type = index >= 0 ? subdirName.substring(0, index) : subdirName;
resourceSet.add(new ResourceEntry(type, FileUtil.getNameWithoutExtension(file.getName())));
}
}
}
private static void waitForSmartMode(Project project) {
if (!ApplicationManager.getApplication().isReadAccessAllowed()) {
DumbService.getInstance(project).waitForSmartMode();
}
}
@NotNull
public static String[] toOsPaths(@NotNull VirtualFile[] classFilesDirs) {
final String[] classFilesDirOsPaths = new String[classFilesDirs.length];
@@ -160,7 +160,7 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
}
@NotNull
private static Set<String> getResourceTypesInCurrentModule(@NotNull AndroidFacet facet) {
public static Set<String> getResourceTypesInCurrentModule(@NotNull AndroidFacet facet) {
final Set<String> result = new HashSet<String>();
final LocalResourceManager manager = facet.getLocalResourceManager();
@@ -173,6 +173,9 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
}
result.addAll(manager.getValueResourceTypes());
if (manager.getIds().size() > 0) {
result.add(ResourceType.ID.getName());
}
return result;
}
@@ -205,17 +208,10 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
String resPackage,
Collection<ResourceValue> result,
boolean explicitResourceType) {
ResourceManager manager = facet.getResourceManager(resPackage);
if (manager == null) return;
for (String name : manager.getValueResourceNames(type)) {
result.add(referenceTo(type, resPackage, name, explicitResourceType));
}
for (String file : manager.getFileResourcesNames(type)) {
result.add(referenceTo(type, resPackage, file, explicitResourceType));
}
if (type.equals("id")) {
for (String id : manager.getIds()) {
result.add(referenceTo(type, resPackage, id, explicitResourceType));
final ResourceManager manager = facet.getResourceManager(resPackage);
if (manager != null) {
for (String name : manager.getResourceNames(type)) {
result.add(referenceTo(type, resPackage, name, explicitResourceType));
}
}
}
@@ -40,7 +40,6 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
@@ -87,7 +86,6 @@ import org.jetbrains.android.sdk.*;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.android.util.ResourceEntry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -446,12 +444,6 @@ public class AndroidFacet extends Facet<AndroidFacetConfiguration> {
return;
}
DumbService.getInstance(project).waitForSmartMode();
final HashSet<ResourceEntry> resourceSet = new HashSet<ResourceEntry>();
AndroidCompileUtil.collectAllResources(AndroidFacet.this, resourceSet);
myListener.setResourceSet(resourceSet);
if (AndroidAptCompiler.isToCompileModule(module, getConfiguration())) {
AndroidCompileUtil.generate(module, AndroidAutogeneratorMode.AAPT);
}
@@ -422,10 +422,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
String absLibsPath = myNativeLibsFolder.getText().trim();
myConfiguration.LIBS_FOLDER_RELATIVE_PATH = absLibsPath.length() > 0 ? '/' + getAndCheckRelativePath(absLibsPath, false) : "";
if (myConfiguration.LIBRARY_PROJECT != myIsLibraryProjectCheckbox.isSelected()) {
runApt = true;
}
myConfiguration.CUSTOM_DEBUG_KEYSTORE_PATH = getSelectedCustomKeystorePath();
myConfiguration.LIBRARY_PROJECT = myIsLibraryProjectCheckbox.isSelected();
@@ -454,9 +450,6 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
boolean useCustomAptSrc = myUseCustomSourceDirectoryRadio.isSelected();
if (myConfiguration.USE_CUSTOM_APK_RESOURCE_FOLDER != useCustomAptSrc) {
runApt = true;
}
myConfiguration.USE_CUSTOM_APK_RESOURCE_FOLDER = useCustomAptSrc;
String absAptSourcePath = myCustomAptSourceDirField.getText().trim();
@@ -464,11 +457,7 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
if (absAptSourcePath.length() == 0) {
throw new ConfigurationException("Resources folder not specified");
}
String newCustomAptSourceFolder = '/' + getAndCheckRelativePath(absAptSourcePath, false);
if (!newCustomAptSourceFolder.equals(myConfiguration.CUSTOM_APK_RESOURCE_FOLDER)) {
runApt = true;
}
myConfiguration.CUSTOM_APK_RESOURCE_FOLDER = newCustomAptSourceFolder;
myConfiguration.CUSTOM_APK_RESOURCE_FOLDER = '/' + getAndCheckRelativePath(absAptSourcePath, false);
}
else {
String relPath = toRelativePath(absAptSourcePath);
@@ -20,11 +20,9 @@ import com.android.resources.ResourceFolderType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.*;
import com.intellij.util.containers.HashSet;
import com.intellij.util.ui.update.MergingUpdateQueue;
import com.intellij.util.ui.update.Update;
import org.jetbrains.android.compiler.AndroidAptCompiler;
@@ -35,14 +33,12 @@ import org.jetbrains.android.fileTypes.AndroidIdlFileType;
import org.jetbrains.android.fileTypes.AndroidRenderscriptFileType;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.android.util.ResourceEntry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import static org.jetbrains.android.util.AndroidUtils.findSourceRoot;
@@ -59,9 +55,6 @@ class AndroidResourceFilesListener extends VirtualFileAdapter {
private final AndroidFacet myFacet;
private String myCachedPackage = null;
private volatile Set<ResourceEntry> myResourceSet = new HashSet<ResourceEntry>();
private static final Object RESOURCES_SET_LOCK = new Object();
public AndroidResourceFilesListener(final AndroidFacet facet) {
myFacet = facet;
myQueue = new MergingUpdateQueue("AndroidResourcesCompilationQueue", 300, true, null, myFacet, null, false);
@@ -128,12 +121,6 @@ class AndroidResourceFilesListener extends VirtualFileAdapter {
}
}
public void setResourceSet(@NotNull Set<ResourceEntry> resourceSet) {
synchronized (RESOURCES_SET_LOCK) {
myResourceSet = resourceSet;
}
}
private class MyUpdate extends Update {
private final VirtualFileEvent myEvent;
@@ -160,23 +147,6 @@ class AndroidResourceFilesListener extends VirtualFileAdapter {
}
for (AndroidAutogeneratorMode autogenerationMode : autogenerationModes) {
if (autogenerationMode == AndroidAutogeneratorMode.AAPT &&
AndroidRootUtil.getManifestFile(myFacet) != myEvent.getFile()) {
final HashSet<ResourceEntry> resourceSet = new HashSet<ResourceEntry>();
DumbService.getInstance(myFacet.getModule().getProject()).waitForSmartMode();
AndroidCompileUtil.collectAllResources(myFacet, resourceSet);
synchronized (RESOURCES_SET_LOCK) {
if (resourceSet.equals(myResourceSet) &&
!myFacet.areSourcesGeneratedWithErrors(AndroidAutogeneratorMode.AAPT)) {
return;
}
myResourceSet = resourceSet;
}
}
AndroidCompileUtil.generate(myFacet.getModule(), autogenerationMode, true);
}
}
@@ -216,7 +186,7 @@ class AndroidResourceFilesListener extends VirtualFileAdapter {
final List<AndroidAutogeneratorMode> modes = new ArrayList<AndroidAutogeneratorMode>();
if (AndroidAptCompiler.isToCompileModule(module, myFacet.getConfiguration()) && (gp == resourceDir || manifestFile == file)) {
if (AndroidAptCompiler.isToCompileModule(module, myFacet.getConfiguration()) && manifestFile == file) {
final Manifest manifest = myFacet.getManifest();
final String aPackage = manifest != null ? manifest.getPackage().getValue() : null;
@@ -262,6 +262,17 @@ public abstract class ResourceManager {
return result;
}
@NotNull
public Collection<String> getResourceNames(@NotNull String type) {
final Set<String> result = new HashSet<String>();
result.addAll(getValueResourceNames(type));
result.addAll(getFileResourcesNames(type));
if (type.equals("id")) {
result.addAll(getIds());
}
return result;
}
@Nullable
public abstract AttributeDefinitions getAttributeDefinitions();
@@ -572,6 +572,15 @@ public class AndroidResourceUtil {
return false;
}
public static boolean isManifestJavaFile(@NotNull AndroidFacet facet, @NotNull PsiFile file) {
if (file.getName().equals(AndroidCommonUtils.MANIFEST_JAVA_FILE_NAME) && file instanceof PsiJavaFile) {
final Manifest manifest = facet.getManifest();
final PsiJavaFile javaFile = (PsiJavaFile)file;
return manifest != null && javaFile.getPackageName().equals(manifest.getPackage().getValue());
}
return false;
}
public static List<String> getNames(@NotNull Collection<ResourceType> resourceTypes) {
if (resourceTypes.size() == 0) {
return Collections.emptyList();
@@ -803,4 +812,9 @@ public class AndroidResourceUtil {
}
return AndroidFileTemplateProvider.RESOURCE_FILE_TEMPLATE;
}
@NotNull
public static String getFieldNameByResourceName(@NotNull String fieldName) {
return fieldName.replace('.', '_').replace('-', '_');
}
}
@@ -109,6 +109,7 @@ public class AndroidUtils {
@NonNls public static final String APPLICATION_CLASS_NAME = "android.app.Application";
@NonNls public static final String ACTIVITY_BASE_CLASS_NAME = "android.app.Activity";
@NonNls public static final String R_CLASS_NAME = "R";
@NonNls public static final String MANIFEST_CLASS_NAME = "Manifest";
@NonNls public static final String LAUNCH_ACTION_NAME = "android.intent.action.MAIN";
@NonNls public static final String LAUNCH_CATEGORY_NAME = "android.intent.category.LAUNCHER";
@NonNls public static final String INSTRUMENTATION_RUNNER_BASE_CLASS = "android.app.Instrumentation";
-8
View File
@@ -1,12 +1,4 @@
package p1.p2;
public final class R {
public static final class string {
public static final int welcome=0x7f040001;
public static final int hello=0x7f040000;
}
public static final class drawable {
public static final int picture3=0x7f040002;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion {
public void f() {
R.layo<caret>
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion {
public void f() {
R.layout
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion {
public void f() {
R.layout.mai<caret>
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion {
public void f() {
R.layout.main
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion {
public void f() {
R.xm<caret>
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion {
public void f() {
R.xm
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaHighlighting1 {
public void f() {
int n = R.<error>xml</error>.main;
}
}
@@ -0,0 +1,7 @@
package p1;
public class JavaHighlighting6 {
public void f() {
int n = p1.p2.R.layout.main;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaHighlighting3 {
public void f() {
int n = R.layout.<error>unknown</error>;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaHighlighting4 {
public void f() {
int n = R.layout.main;
}
}
@@ -0,0 +1,7 @@
package p1;
public class JavaHighlighting5 {
public void f() {
int n = <error>R</error>.layout.main;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaIdCompletion {
public void f() {
int n = R.id.myComp<caret>;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaIdCompletion {
public void f() {
int n = R.id.myComponent;
}
}
@@ -0,0 +1,3 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:id="@+id/myComponent"/>
</LinearLayout>
@@ -0,0 +1,17 @@
package p1.p2;
import java.lang.String;
public class JavaCompletion {
public void f() {
String s = Manifest.permission.perm1;
s = Manifest.permission.perm2;
s = Manifest.permission.<error>unknown</error>;
s = Manifest.<error>permissio</error>.perm1;
s = Manifest.permission.aba_perm;
s = Manifest.permission_group.group1;
s = Manifest.permission_group.<error>unknown</error>;
s = Manifest.permission_group.aba_group;
}
}
@@ -0,0 +1,4 @@
package p1.p2;
public class Manifest {
}
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="p1.p2">
<permission android:name="android.permission.perm1"/>
<permission android:name="aba.perm2"/>
<permission android:name="android.aba-perm"/>
<permission-group android:name="android.permission-group.group1"/>
<permission-group android:name="group2"/>
<permission-group android:name="android.permission-group.aba_group"/>
</manifest>
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion1 {
public void f() {
int n = R.string.my_str<caret>;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion1 {
public void f() {
int n = R.string.my_string;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion1 {
public void f() {
int n = R.stri<caret>;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion1 {
public void f() {
int n = R.string;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion1 {
public void f() {
int n = R.string.unknow<caret>;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion1 {
public void f() {
int n = R.string.unknow;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion1 {
public void f() {
int n = R.style.Theme_My<caret>;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion1 {
public void f() {
int n = R.style.Theme_MyCustomStyle
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion1 {
public void f() {
int n = R.string.my_string;
}
}
@@ -0,0 +1,7 @@
package p1.p2;
public class JavaCompletion1 {
public void f() {
int n = R.string.<error>unknown</error>;
}
}
@@ -0,0 +1,4 @@
<resources>
<string name="my_string">abacaba</string>
<style name="Theme.MyCustomStyle" parent="android:style/Theme.Dialog"></style>
</resources>
@@ -39,6 +39,14 @@ abstract class AndroidDomTest extends AndroidTestCase {
return "dom/res";
}
protected void doTestJavaCompletion(String aPackage) throws Throwable {
final String fileName = getTestName(false) + ".java";
final VirtualFile file = copyFileToProject(fileName, "src/" + aPackage.replace('/', '.') + '/' + fileName);
myFixture.configureFromExistingVirtualFile(file);
myFixture.complete(CompletionType.BASIC);
myFixture.checkResultByFile(testFolder + '/' + getTestName(false) + "_after.java");
}
protected static String[] withNamespace(String... arr) {
List<String> list = new ArrayList<String>();
for (String s : arr) {
@@ -66,6 +74,13 @@ abstract class AndroidDomTest extends AndroidTestCase {
myFixture.checkHighlighting(true, false, false);
}
protected void doTestJavaHighlighting(String aPackage) throws Throwable {
final String fileName = getTestName(false) + ".java";
final VirtualFile virtualFile = copyFileToProject(fileName, "src/" + aPackage.replace('.', '/') + '/' + fileName);
myFixture.configureFromExistingVirtualFile(virtualFile);
myFixture.checkHighlighting(true, false, false);
}
protected void doTestCompletion() throws Throwable {
doTestCompletion(true);
}
@@ -385,5 +385,50 @@ public class AndroidLayoutDomTest extends AndroidDomTest {
copyFileToProject("OnClick_Class3.java", "src/p1/p2/OnClick_Class3.java");
copyFileToProject("OnClick_Class4.java", "src/p1/p2/OnClick_Class4.java");
}
public void testJavaCompletion1() throws Throwable {
copyFileToProject("main.xml", "res/layout/main.xml");
doTestJavaCompletion("p1.p2");
}
public void testJavaCompletion2() throws Throwable {
copyFileToProject("main.xml", "res/layout/main.xml");
doTestJavaCompletion("p1.p2");
}
public void testJavaCompletion3() throws Throwable {
copyFileToProject("main.xml", "res/layout/main.xml");
doTestJavaCompletion("p1.p2");
}
public void testJavaIdCompletion() throws Throwable {
copyFileToProject("main.xml", "res/layout/main.xml");
doTestJavaCompletion("p1.p2");
}
public void testJavaHighlighting1() throws Throwable {
copyFileToProject("main.xml", "res/layout/main.xml");
doTestJavaHighlighting("p1.p2");
}
public void testJavaHighlighting2() throws Throwable {
copyFileToProject("main.xml", "res/layout/main.xml");
doTestJavaHighlighting("p1");
}
public void testJavaHighlighting3() throws Throwable {
copyFileToProject("main.xml", "res/layout/main.xml");
doTestJavaHighlighting("p1.p2");
}
public void testJavaHighlighting4() throws Throwable {
copyFileToProject("main.xml", "res/layout/main.xml");
doTestJavaHighlighting("p1.p2");
}
public void testJavaHighlighting5() throws Throwable {
copyFileToProject("main.xml", "res/layout/main.xml");
doTestJavaHighlighting("p1");
}
}
@@ -192,4 +192,11 @@ public class AndroidManifestDomTest extends AndroidDomTest {
copyFileToProject("myIntResource.xml", "res/values/myIntResource.xml");
doTestCompletion();
}
public void testJavaHighlighting() throws Throwable {
copyFileToProject("PermissionsManifest.xml", "AndroidManifest.xml");
copyFileToProject("Manifest.java", "src/p1/p2/Manifest.java");
doTestJavaHighlighting("p1.p2");
}
}
@@ -215,4 +215,34 @@ public class AndroidValueResourcesTest extends AndroidDomTest {
}.execute();
myFixture.checkResultByFile(testFolder + '/' + getTestName(true) + "_after.xml", true);
}
public void testJavaCompletion1() throws Throwable {
copyFileToProject("value_resources.xml", "res/values/value_resources.xml");
doTestJavaCompletion("p1.p2");
}
public void testJavaCompletion2() throws Throwable {
copyFileToProject("value_resources.xml", "res/values/value_resources.xml");
doTestJavaCompletion("p1.p2");
}
public void testJavaCompletion3() throws Throwable {
copyFileToProject("value_resources.xml", "res/values/value_resources.xml");
doTestJavaCompletion("p1.p2");
}
public void testJavaCompletion4() throws Throwable {
copyFileToProject("value_resources.xml", "res/values/value_resources.xml");
doTestJavaCompletion("p1.p2");
}
public void testJavaHighlighting1() throws Throwable {
copyFileToProject("value_resources.xml", "res/values/value_resources.xml");
doTestJavaHighlighting("p1.p2");
}
public void testJavaHighlighting2() throws Throwable {
copyFileToProject("value_resources.xml", "res/values/value_resources.xml");
doTestJavaHighlighting("p1.p2");
}
}