1d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver/*
2d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * Copyright 2014, Google Inc.
3d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * All rights reserved.
4d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver *
5d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * Redistribution and use in source and binary forms, with or without
6d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * modification, are permitted provided that the following conditions are
7d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * met:
8d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver *
9d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver *     * Redistributions of source code must retain the above copyright
10d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * notice, this list of conditions and the following disclaimer.
11d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver *     * Redistributions in binary form must reproduce the above
12d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * copyright notice, this list of conditions and the following disclaimer
13d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * in the documentation and/or other materials provided with the
14d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * distribution.
15d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver *     * Neither the name of Google Inc. nor the names of its
16d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * contributors may be used to endorse or promote products derived from
17d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * this software without specific prior written permission.
18d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver *
19d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver */
31d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver
32d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruverpackage org.jf.smalidea.psi.impl;
33d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver
3431aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruverimport com.intellij.openapi.util.TextRange;
3531aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruverimport com.intellij.psi.*;
3607e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruverimport com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
371570315fcf558d18de6fd24a16ba4e13e73727feBen Gruverimport com.intellij.psi.infos.CandidateInfo;
389a1db48dc5519a9628418a90be175b69ed375f9fBen Gruverimport com.intellij.psi.scope.PsiScopeProcessor;
3931aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruverimport com.intellij.util.IncorrectOperationException;
40db1b08807f7a71053e49e73306636ff12579afcfBen Gruverimport org.jetbrains.annotations.NotNull;
4131aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruverimport org.jetbrains.annotations.Nullable;
42d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruverimport org.jf.smalidea.psi.SmaliCompositeElementFactory;
43d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruverimport org.jf.smalidea.psi.SmaliElementTypes;
4407e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruverimport org.jf.smalidea.psi.leaf.SmaliClassDescriptor;
45db1b08807f7a71053e49e73306636ff12579afcfBen Gruverimport org.jf.smalidea.util.NameUtils;
46d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver
473048a6c897ba18bf8d7770e64ed3fc4299dbcedeBen Gruverpublic class SmaliClassTypeElement extends SmaliTypeElement implements PsiJavaCodeReferenceElement {
486a520231e74c1045e43f4b34182562979fbfc988Ben Gruver    public static final SmaliClassTypeElement[] EMPTY_ARRAY = new SmaliClassTypeElement[0];
496a520231e74c1045e43f4b34182562979fbfc988Ben Gruver
50d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver    public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() {
51d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver        @Override public SmaliCompositeElement createElement() {
52d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver            return new SmaliClassTypeElement();
53d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver        }
54d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver    };
55d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver
5631aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @Nullable private SmaliClassType classType = null;
5731aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
58d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver    public SmaliClassTypeElement() {
59d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver        super(SmaliElementTypes.CLASS_TYPE);
60d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver    }
61db1b08807f7a71053e49e73306636ff12579afcfBen Gruver
6231aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @NotNull @Override public SmaliClassType getType() {
6331aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        if (classType == null) {
6431aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver            classType = new SmaliClassType(this);
6531aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        }
6631aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        return classType;
6731aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
6831aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
6931aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @Override public String getName() {
7031aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        return NameUtils.shortNameFromQualifiedName(getCanonicalText());
7131aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
7231aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
739a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    @Nullable @Override public SmaliClassTypeElement getInnermostComponentReferenceElement() {
749a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver        return this;
7531aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
7631aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
7731aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @Override public PsiElement getElement() {
7831aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        return this;
7931aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
8031aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
8131aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @Override public PsiReference getReference() {
8231aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        return this;
8331aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
8431aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
8531aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @Override public TextRange getRangeInElement() {
8631aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        return new TextRange(0, getTextLength());
8731aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
8831aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
8981d77d0dabbf303a10c9b018fbd752cd87fff58aBen Gruver    @Nullable @Override public PsiClass resolve() {
9082f031210ea1913abdb2a26b1f461826ee9980faBen Gruver        return NameUtils.resolveSmaliType(this, getText());
9131aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
9231aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
9331aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @NotNull @Override public String getCanonicalText() {
9482f031210ea1913abdb2a26b1f461826ee9980faBen Gruver        return getQualifiedName();
9531aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
9631aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
9731aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @Override public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
9807e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver        SmaliClassDescriptor descriptor = getReferenceNameElement();
9907e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver        if (descriptor == null) {
10007e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver            throw new IncorrectOperationException();
10107e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver        }
10207e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver
10307e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver        SmaliClassDescriptor newDescriptor = new SmaliClassDescriptor(NameUtils.javaToSmaliType(newElementName));
10407e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver        CodeEditUtil.setNodeGenerated(newDescriptor, true);
10507e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver
10607e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver        this.replaceChild(descriptor, newDescriptor);
10707e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver        return this;
10831aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
10931aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
11031aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @Override public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
11107e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver        if (element instanceof PsiClass) {
11207e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver            handleElementRename(((PsiClass) element).getQualifiedName());
11307e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver            return this;
11407e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver        }
11531aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        throw new IncorrectOperationException();
11631aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
11731aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
11831aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @Override public boolean isReferenceTo(PsiElement element) {
119694fb7ca906eb67a19a2f2483dba7a326796caceBen Gruver        if (!(element instanceof PsiClass)) {
12031aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver            return false;
12131aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        }
12231aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        return element.getManager().areElementsEquivalent(element, resolve());
12331aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
12431aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
12531aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @NotNull @Override public Object[] getVariants() {
12631aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        // TODO: implement this?
12731aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        return new Object[0];
12831aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
12931aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
13031aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    @Override public boolean isSoft() {
13131aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver        return false;
13231aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver    }
13331aad6b5cdc1788a9e0a08938acc84bca6b1a307Ben Gruver
1349a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    // ***************************************************************************
1359a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    // Below are the PsiJavaCodeReferenceElement-specific methods
1369a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver
1379a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    @Override public void processVariants(@NotNull PsiScopeProcessor processor) {
1389a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver        // TODO: maybe just do nothing?
1399a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver        throw new UnsupportedOperationException();
1409a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    }
1419a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver
14207e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver    @Nullable @Override public SmaliClassDescriptor getReferenceNameElement() {
14307e6ade7fe18de33439db0f3177c01ef7f7f14c2Ben Gruver        return findChildByClass(SmaliClassDescriptor.class);
1449a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    }
1459a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver
1469a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    @Nullable @Override public PsiReferenceParameterList getParameterList() {
1479a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver        // TODO: (generics) implement this
1489a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver        return null;
1499a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    }
1509a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver
1519a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    @NotNull @Override public PsiType[] getTypeParameters() {
1529a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver        // TODO: (generics) implement this
1539a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver        return new PsiType[0];
1549a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    }
1559a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver
1569a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    @Override public boolean isQualified() {
1579a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver        // TODO: should this return false for classes in the top level package?
1589a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver        return true;
1599a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    }
1609a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver
1619a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    @Override public String getQualifiedName() {
16282f031210ea1913abdb2a26b1f461826ee9980faBen Gruver        PsiClass psiClass = resolve();
16382f031210ea1913abdb2a26b1f461826ee9980faBen Gruver        if (psiClass != null) {
16482f031210ea1913abdb2a26b1f461826ee9980faBen Gruver            return psiClass.getQualifiedName();
16582f031210ea1913abdb2a26b1f461826ee9980faBen Gruver        }
16682f031210ea1913abdb2a26b1f461826ee9980faBen Gruver        return NameUtils.smaliToJavaType(getText());
1679a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    }
1689a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver
1699a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    @NotNull @Override public JavaResolveResult advancedResolve(boolean incompleteCode) {
1701570315fcf558d18de6fd24a16ba4e13e73727feBen Gruver        PsiClass element = resolve();
1711570315fcf558d18de6fd24a16ba4e13e73727feBen Gruver        if (element == null) {
1721570315fcf558d18de6fd24a16ba4e13e73727feBen Gruver            return JavaResolveResult.EMPTY;
1731570315fcf558d18de6fd24a16ba4e13e73727feBen Gruver        }
1741570315fcf558d18de6fd24a16ba4e13e73727feBen Gruver        return new CandidateInfo(element, PsiSubstitutor.EMPTY);
1759a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    }
1769a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver
1779a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    @NotNull @Override public JavaResolveResult[] multiResolve(boolean incompleteCode) {
1781570315fcf558d18de6fd24a16ba4e13e73727feBen Gruver        PsiClass element = resolve();
1791570315fcf558d18de6fd24a16ba4e13e73727feBen Gruver        if (element == null) {
1801570315fcf558d18de6fd24a16ba4e13e73727feBen Gruver            return JavaResolveResult.EMPTY_ARRAY;
1811570315fcf558d18de6fd24a16ba4e13e73727feBen Gruver        }
1821570315fcf558d18de6fd24a16ba4e13e73727feBen Gruver        return new CandidateInfo[] { new CandidateInfo(element, PsiSubstitutor.EMPTY) };
1839a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    }
1849a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver
1859a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    @Nullable @Override public PsiElement getQualifier() {
186923cc91ea26693cad32056f9a08eca432f3e4c61Ben Gruver        return null;
1879a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    }
1889a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver
1899a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    @Nullable @Override public String getReferenceName() {
1909a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver        return getName();
1919a1db48dc5519a9628418a90be175b69ed375f9fBen Gruver    }
192d05c6f0f2bc33c4c3681b4e64232ba1ec7275521Ben Gruver}
193