Search in sources :

Example 1 with PsiDataBindingResourceItem

use of com.android.tools.idea.res.PsiDataBindingResourceItem in project android by JetBrains.

the class DataBindingConverter method toString.

@Nullable
@Override
public String toString(@Nullable final PsiClass psiClass, final ConvertContext context) {
    if (psiClass == null) {
        return null;
    }
    final String qualifiedName = psiClass.getName();
    // try and replace with import if possible.
    final DataBindingInfo bindingInfo = getDataBindingInfo(context);
    if (bindingInfo != null) {
        int longestPrefix = 0;
        PsiDataBindingResourceItem longestImport = null;
        for (final PsiDataBindingResourceItem anImport : bindingInfo.getItems(DataBindingResourceType.IMPORT)) {
            // Try and find the longest matching import. For inner classes, either the outer or the inner class may be imported.
            final String prefix = getLongestPrefix(anImport.getTypeDeclaration(), qualifiedName);
            if (prefix.length() > longestPrefix) {
                if (qualifiedName.length() == prefix.length()) {
                    return AndroidLayoutUtil.getAlias(anImport);
                }
                final char c = qualifiedName.charAt(prefix.length());
                if (c == '.') {
                    longestPrefix = prefix.length();
                    longestImport = anImport;
                }
            }
        }
        if (longestImport != null) {
            return AndroidLayoutUtil.getAlias(longestImport) + qualifiedName.substring(longestPrefix);
        }
    }
    if (qualifiedName.startsWith(JAVA_LANG)) {
        return qualifiedName.substring(JAVA_LANG.length());
    }
    return qualifiedName;
}
Also used : PsiDataBindingResourceItem(com.android.tools.idea.res.PsiDataBindingResourceItem) DataBindingInfo(com.android.tools.idea.res.DataBindingInfo) Nullable(org.jetbrains.annotations.Nullable)

Example 2 with PsiDataBindingResourceItem

use of com.android.tools.idea.res.PsiDataBindingResourceItem in project android by JetBrains.

the class DataBindingConverter method getQualifiedType.

/**
   * Get the fully qualified name of the class referenced by {@code nameOrAlias}.
   * <p/>
   * It is not guaranteed that the class will exist. Also, the name returned here uses '.' for inner classes (like import declarations) and
   * not '$' as used by JVM.
   *
   * @param nameOrAlias     a fully qualified name, or an alias as declared in an {@code <import>} or an inner class of the alias.
   * @param dataBindingInfo for getting the list of {@code <import>} tags.
   * @return the fully qualified name. This does not guarantee that the class will exist.
   */
public static String getQualifiedType(@Nullable String nameOrAlias, @Nullable final DataBindingInfo dataBindingInfo) {
    if (nameOrAlias == null) {
        return null;
    }
    nameOrAlias = nameOrAlias.replace('$', '.');
    if (dataBindingInfo == null) {
        return nameOrAlias;
    }
    final int i = nameOrAlias.indexOf('.');
    final String alias = i >= 0 ? nameOrAlias.substring(0, i) : nameOrAlias;
    PsiDataBindingResourceItem imp = getImport(alias, dataBindingInfo);
    if (imp != null) {
        final String type = imp.getTypeDeclaration();
        if (type != null) {
            return nameOrAlias.equals(alias) ? type : type + nameOrAlias.substring(alias.length());
        }
    }
    return nameOrAlias;
}
Also used : PsiDataBindingResourceItem(com.android.tools.idea.res.PsiDataBindingResourceItem)

Example 3 with PsiDataBindingResourceItem

use of com.android.tools.idea.res.PsiDataBindingResourceItem in project android by JetBrains.

the class DataBindingConverter method createReferences.

@NotNull
@Override
public PsiReference[] createReferences(final GenericDomValue<PsiClass> value, final PsiElement element, final ConvertContext context) {
    assert element instanceof XmlAttributeValue;
    final XmlAttributeValue attrValue = (XmlAttributeValue) element;
    final String strValue = attrValue.getValue();
    final int start = attrValue.getValueTextRange().getStartOffset() - attrValue.getTextRange().getStartOffset();
    List<PsiReference> result = new ArrayList<>();
    final String[] nameParts = strValue.split("[$.]");
    Module module = context.getModule();
    if (nameParts.length == 0 || module == null) {
        return PsiReference.EMPTY_ARRAY;
    }
    int offset = start;
    // Check if the first namePart is an alias.
    DataBindingInfo bindingInfo = getDataBindingInfo(context);
    // for iterating over the nameParts.
    int idx = 0;
    // difference in lengths of the "type" and the "alias". Used in range computation later.
    int diff = 0;
    String fullType = strValue.replace('$', '.');
    if (bindingInfo != null) {
        String alias = nameParts[idx];
        PsiDataBindingResourceItem anImport = getImport(alias, bindingInfo);
        if (anImport != null) {
            // Found an import matching the first namePart. Add a reference from this to the type.
            idx++;
            TextRange range = new TextRange(offset, offset += alias.length());
            // Skip the next dot or dollar separator (if any)
            offset++;
            String type = anImport.getTypeDeclaration();
            result.add(new AliasedReference(element, range, type, module));
            fullType = type + fullType.substring(alias.length());
            diff = type.length() - alias.length();
        } else {
            //  Check java.lang and primitives
            if (nameParts.length == 1) {
                if (alias.length() > 0) {
                    if (Character.isLowerCase(alias.charAt(0))) {
                        final PsiPrimitiveType primitive = PsiJavaParserFacadeImpl.getPrimitiveType(alias);
                        if (primitive != null) {
                            result.add(new PsiReferenceBase<PsiElement>(element, true) {

                                @Nullable
                                @Override
                                public PsiElement resolve() {
                                    return myElement;
                                }

                                @NotNull
                                @Override
                                public Object[] getVariants() {
                                    return ArrayUtil.EMPTY_OBJECT_ARRAY;
                                }
                            });
                        }
                    } else {
                        // java.lang
                        PsiClass aClass = JavaPsiFacade.getInstance(context.getProject()).findClass(JAVA_LANG + alias, GlobalSearchScope.moduleWithLibrariesScope(module));
                        if (aClass != null) {
                            final TextRange range = new TextRange(offset, offset += alias.length());
                            result.add(new ClassReference(element, range, aClass));
                        }
                    }
                    idx++;
                }
            }
        }
    }
    for (; idx < nameParts.length; idx++, offset++) {
        final String packageName = nameParts[idx];
        if (packageName.length() > 0) {
            final TextRange range = new TextRange(offset, offset += packageName.length());
            result.add(new AliasedReference(element, range, fullType.substring(0, diff + offset - start), module));
        }
    }
    return result.toArray(new PsiReference[result.size()]);
}
Also used : PsiDataBindingResourceItem(com.android.tools.idea.res.PsiDataBindingResourceItem) ArrayList(java.util.ArrayList) TextRange(com.intellij.openapi.util.TextRange) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) DataBindingInfo(com.android.tools.idea.res.DataBindingInfo) NotNull(org.jetbrains.annotations.NotNull) Module(com.intellij.openapi.module.Module) Nullable(org.jetbrains.annotations.Nullable) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with PsiDataBindingResourceItem

use of com.android.tools.idea.res.PsiDataBindingResourceItem in project android by JetBrains.

the class LightBindingClass method processDeclarations.

@Override
public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place) {
    boolean continueProcessing = super.processDeclarations(processor, state, lastParent, place);
    if (!continueProcessing) {
        return false;
    }
    List<PsiDataBindingResourceItem> imports = myInfo.getItems(DataBindingResourceType.IMPORT);
    if (imports.isEmpty()) {
        return true;
    }
    final ElementClassHint classHint = processor.getHint(ElementClassHint.KEY);
    if (classHint != null && classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) {
        final NameHint nameHint = processor.getHint(NameHint.KEY);
        final String name = nameHint != null ? nameHint.getName(state) : null;
        for (PsiDataBindingResourceItem imp : imports) {
            String alias = imp.getExtra(SdkConstants.ATTR_ALIAS);
            if (alias != null) {
                // aliases are pre-resolved in {@linkplain #replaceImportAliases}
                continue;
            }
            String qName = imp.getExtra(SdkConstants.ATTR_TYPE);
            if (qName == null) {
                continue;
            }
            if (name != null && !qName.endsWith("." + name)) {
                continue;
            }
            Module module = myInfo.getModule();
            if (module == null) {
                // this should not really happen but just to be safe
                return true;
            }
            PsiClass aClass = JavaPsiFacade.getInstance(myManager.getProject()).findClass(qName, module.getModuleWithDependenciesAndLibrariesScope(true));
            if (aClass != null) {
                if (!processor.execute(aClass, state)) {
                    // found it!
                    return false;
                }
            }
        }
    }
    return true;
}
Also used : PsiDataBindingResourceItem(com.android.tools.idea.res.PsiDataBindingResourceItem) ElementClassHint(com.intellij.psi.scope.ElementClassHint) NameHint(com.intellij.psi.scope.NameHint) Module(com.intellij.openapi.module.Module)

Aggregations

PsiDataBindingResourceItem (com.android.tools.idea.res.PsiDataBindingResourceItem)4 DataBindingInfo (com.android.tools.idea.res.DataBindingInfo)2 Module (com.intellij.openapi.module.Module)2 Nullable (org.jetbrains.annotations.Nullable)2 TextRange (com.intellij.openapi.util.TextRange)1 ElementClassHint (com.intellij.psi.scope.ElementClassHint)1 NameHint (com.intellij.psi.scope.NameHint)1 XmlAttributeValue (com.intellij.psi.xml.XmlAttributeValue)1 ArrayList (java.util.ArrayList)1 NotNull (org.jetbrains.annotations.NotNull)1