001 /* 002 * Copyright 2010-2015 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.kotlin.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.kotlin.psi.psiUtil.PsiUtilPackage; 025 import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub; 026 import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes; 027 import org.jetbrains.kotlin.name.FqName; 028 import org.jetbrains.kotlin.name.Name; 029 import org.jetbrains.kotlin.name.SpecialNames; 030 031 import java.util.Collections; 032 import java.util.List; 033 034 public class JetPackageDirective extends JetModifierListOwnerStub<KotlinPlaceHolderStub<JetPackageDirective>> implements JetReferenceExpression { 035 private String qualifiedNameCache = null; 036 037 public JetPackageDirective(@NotNull ASTNode node) { 038 super(node); 039 } 040 041 public JetPackageDirective(@NotNull KotlinPlaceHolderStub<JetPackageDirective> stub) { 042 super(stub, JetStubElementTypes.PACKAGE_DIRECTIVE); 043 } 044 045 // This should be either JetSimpleNameExpression, or JetDotQualifiedExpression 046 @Nullable 047 public JetExpression getPackageNameExpression() { 048 return JetStubbedPsiUtil.getStubOrPsiChild(this, JetStubElementTypes.INSIDE_DIRECTIVE_EXPRESSIONS, JetExpression.ARRAY_FACTORY); 049 } 050 051 @NotNull 052 public List<JetSimpleNameExpression> getPackageNames() { 053 JetExpression nameExpression = getPackageNameExpression(); 054 if (nameExpression == null) return Collections.emptyList(); 055 056 List<JetSimpleNameExpression> packageNames = ContainerUtil.newArrayList(); 057 while (nameExpression instanceof JetQualifiedExpression) { 058 JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) nameExpression; 059 060 JetExpression selector = qualifiedExpression.getSelectorExpression(); 061 if (selector instanceof JetSimpleNameExpression) { 062 packageNames.add((JetSimpleNameExpression) selector); 063 } 064 065 nameExpression = qualifiedExpression.getReceiverExpression(); 066 } 067 068 if (nameExpression instanceof JetSimpleNameExpression) { 069 packageNames.add((JetSimpleNameExpression) nameExpression); 070 } 071 072 Collections.reverse(packageNames); 073 074 return packageNames; 075 } 076 077 @Nullable 078 public JetSimpleNameExpression getLastReferenceExpression() { 079 JetExpression nameExpression = getPackageNameExpression(); 080 if (nameExpression == null) return null; 081 082 return (JetSimpleNameExpression)PsiUtilPackage.getQualifiedElementSelector(nameExpression); 083 } 084 085 @Nullable 086 public PsiElement getNameIdentifier() { 087 JetSimpleNameExpression lastPart = getLastReferenceExpression(); 088 return lastPart != null ? lastPart.getIdentifier() : null; 089 } 090 091 @Override 092 @NotNull 093 public String getName() { 094 PsiElement nameIdentifier = getNameIdentifier(); 095 return nameIdentifier == null ? "" : nameIdentifier.getText(); 096 } 097 098 @NotNull 099 public Name getNameAsName() { 100 PsiElement nameIdentifier = getNameIdentifier(); 101 return nameIdentifier == null ? SpecialNames.ROOT_PACKAGE : Name.identifier(nameIdentifier.getText()); 102 } 103 104 public boolean isRoot() { 105 return getName().length() == 0; 106 } 107 108 @NotNull 109 public FqName getFqName() { 110 String qualifiedName = getQualifiedName(); 111 return qualifiedName.isEmpty() ? FqName.ROOT : new FqName(qualifiedName); 112 } 113 114 @NotNull 115 public FqName getFqName(JetSimpleNameExpression nameExpression) { 116 return new FqName(getQualifiedNameOf(nameExpression)); 117 } 118 119 @NotNull 120 public String getQualifiedName() { 121 if (qualifiedNameCache == null) { 122 qualifiedNameCache = getQualifiedNameOf(null); 123 } 124 125 return qualifiedNameCache; 126 } 127 128 @NotNull 129 private String getQualifiedNameOf(@Nullable JetSimpleNameExpression nameExpression) { 130 StringBuilder builder = new StringBuilder(); 131 for (JetSimpleNameExpression e : getPackageNames()) { 132 if (builder.length() > 0) { 133 builder.append("."); 134 } 135 builder.append(e.getReferencedName()); 136 137 if (e == nameExpression) break; 138 } 139 return builder.toString(); 140 } 141 142 @Override 143 public void subtreeChanged() { 144 qualifiedNameCache = null; 145 } 146 147 @Override 148 public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) { 149 return visitor.visitPackageDirective(this, data); 150 } 151 } 152