001    /*
002     * Copyright 2010-2014 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.jet.lang.psi;
018    
019    import com.intellij.lang.ASTNode;
020    import com.intellij.psi.PsiElement;
021    import com.intellij.util.containers.ContainerUtil;
022    import org.jetbrains.annotations.NotNull;
023    import org.jetbrains.annotations.Nullable;
024    import org.jetbrains.jet.lang.psi.psiUtil.PsiUtilPackage;
025    import org.jetbrains.jet.lang.resolve.name.FqName;
026    import org.jetbrains.jet.lang.resolve.name.Name;
027    import org.jetbrains.jet.lang.resolve.name.SpecialNames;
028    
029    import java.util.Collections;
030    import java.util.List;
031    
032    public class JetPackageDirective extends JetReferenceExpression {
033        private String qualifiedNameCache = null;
034    
035        public JetPackageDirective(@NotNull ASTNode node) {
036            super(node);
037        }
038    
039        // This should be either JetSimpleNameExpression, or JetDotQualifiedExpression
040        @Nullable
041        public JetExpression getPackageNameExpression() {
042            return findChildByClass(JetExpression.class);
043        }
044    
045        @NotNull
046        public List<JetSimpleNameExpression> getPackageNames() {
047            JetExpression nameExpression = getPackageNameExpression();
048            if (nameExpression == null) return Collections.emptyList();
049    
050            List<JetSimpleNameExpression> packageNames = ContainerUtil.newArrayList();
051            while (nameExpression instanceof JetQualifiedExpression) {
052                JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) nameExpression;
053    
054                JetExpression selector = qualifiedExpression.getSelectorExpression();
055                if (selector instanceof JetSimpleNameExpression) {
056                    packageNames.add((JetSimpleNameExpression) selector);
057                }
058    
059                nameExpression = qualifiedExpression.getReceiverExpression();
060            }
061    
062            if (nameExpression instanceof JetSimpleNameExpression) {
063                packageNames.add((JetSimpleNameExpression) nameExpression);
064            }
065    
066            Collections.reverse(packageNames);
067    
068            return packageNames;
069        }
070    
071        @Nullable
072        public JetSimpleNameExpression getLastReferenceExpression() {
073            JetExpression nameExpression = getPackageNameExpression();
074            if (nameExpression == null) return null;
075    
076            return (JetSimpleNameExpression)PsiUtilPackage.getQualifiedElementSelector(nameExpression);
077        }
078    
079        @Nullable
080        public PsiElement getNameIdentifier() {
081            JetSimpleNameExpression lastPart = getLastReferenceExpression();
082            return lastPart != null ? lastPart.getIdentifier() : null;
083        }
084    
085        @Override
086        @NotNull
087        public String getName() {
088            PsiElement nameIdentifier = getNameIdentifier();
089            return nameIdentifier == null ? "" : nameIdentifier.getText();
090        }
091    
092        @NotNull
093        public Name getNameAsName() {
094            PsiElement nameIdentifier = getNameIdentifier();
095            return nameIdentifier == null ? SpecialNames.ROOT_PACKAGE : Name.identifier(nameIdentifier.getText());
096        }
097    
098        public boolean isRoot() {
099            return getName().length() == 0;
100        }
101    
102        @NotNull
103        public FqName getFqName() {
104            String qualifiedName = getQualifiedName();
105            return qualifiedName.isEmpty() ? FqName.ROOT : new FqName(qualifiedName);
106        }
107    
108        @NotNull
109        public FqName getFqName(JetSimpleNameExpression nameExpression) {
110            return new FqName(getQualifiedNameOf(nameExpression));
111        }
112    
113        @NotNull
114        public String getQualifiedName() {
115            if (qualifiedNameCache == null) {
116                qualifiedNameCache = getQualifiedNameOf(null);
117            }
118    
119            return qualifiedNameCache;
120        }
121    
122        @NotNull
123        private String getQualifiedNameOf(@Nullable JetSimpleNameExpression nameExpression) {
124            StringBuilder builder = new StringBuilder();
125            for (JetSimpleNameExpression e : getPackageNames()) {
126                if (builder.length() > 0) {
127                    builder.append(".");
128                }
129                builder.append(e.getReferencedName());
130    
131                if (e == nameExpression) break;
132            }
133            return builder.toString();
134        }
135    
136        @Override
137        public void subtreeChanged() {
138            qualifiedNameCache = null;
139        }
140    }
141