| /* |
| * Copyright 2000-2013 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.intellij.psi.impl.source; |
| |
| import com.intellij.lang.ASTNode; |
| import com.intellij.psi.*; |
| import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; |
| import com.intellij.psi.impl.java.stubs.PsiImportListStub; |
| import com.intellij.psi.impl.source.tree.ElementType; |
| import com.intellij.psi.impl.source.tree.JavaElementType; |
| import com.intellij.psi.tree.TokenSet; |
| import com.intellij.util.ArrayFactory; |
| import com.intellij.util.containers.HashMap; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.util.Map; |
| |
| public class PsiImportListImpl extends JavaStubPsiElement<PsiImportListStub> implements PsiImportList { |
| private volatile Map<String,PsiImportStatement> myClassNameToImportMap = null; |
| private volatile Map<String,PsiImportStatement> myPackageNameToImportMap = null; |
| private volatile Map<String,PsiImportStatementBase> myNameToSingleImportMap = null; |
| private static final PsiImportStatementBase[] EMPTY_ARRAY = new PsiImportStatementBase[0]; |
| private static final ArrayFactory<PsiImportStatementBase> ARRAY_FACTORY = new ArrayFactory<PsiImportStatementBase>() { |
| @NotNull |
| @Override |
| public PsiImportStatementBase[] create(final int count) { |
| return count == 0 ? EMPTY_ARRAY : new PsiImportStatementBase[count]; |
| } |
| }; |
| |
| public PsiImportListImpl(final PsiImportListStub stub) { |
| super(stub, JavaStubElementTypes.IMPORT_LIST); |
| } |
| |
| public PsiImportListImpl(final ASTNode node) { |
| super(node); |
| } |
| |
| @Override |
| protected Object clone() { |
| PsiImportListImpl clone = (PsiImportListImpl)super.clone(); |
| clone.myClassNameToImportMap = null; |
| clone.myPackageNameToImportMap = null; |
| clone.myNameToSingleImportMap = null; |
| return clone; |
| } |
| |
| @Override |
| public void subtreeChanged() { |
| myClassNameToImportMap = null; |
| myPackageNameToImportMap = null; |
| myNameToSingleImportMap = null; |
| super.subtreeChanged(); |
| } |
| |
| private static final TokenSet IMPORT_STATEMENT_BIT_SET = TokenSet.create(JavaElementType.IMPORT_STATEMENT); |
| private static final TokenSet IMPORT_STATIC_STATEMENT_BIT_SET = TokenSet.create(JavaElementType.IMPORT_STATIC_STATEMENT); |
| |
| @Override |
| @NotNull |
| public PsiImportStatement[] getImportStatements() { |
| return getStubOrPsiChildren(IMPORT_STATEMENT_BIT_SET, PsiImportStatementImpl.ARRAY_FACTORY); |
| } |
| |
| @Override |
| @NotNull |
| public PsiImportStaticStatement[] getImportStaticStatements() { |
| return getStubOrPsiChildren(IMPORT_STATIC_STATEMENT_BIT_SET, PsiImportStaticStatementImpl.ARRAY_FACTORY); |
| } |
| |
| @Override |
| @NotNull |
| public PsiImportStatementBase[] getAllImportStatements() { |
| return getStubOrPsiChildren(ElementType.IMPORT_STATEMENT_BASE_BIT_SET, ARRAY_FACTORY); |
| } |
| |
| @Override |
| public PsiImportStatement findSingleClassImportStatement(String name) { |
| while (true) { |
| Map<String, PsiImportStatement> map = myClassNameToImportMap; |
| if (map == null) { |
| initializeMaps(); |
| } |
| else { |
| return map.get(name); |
| } |
| } |
| } |
| |
| @Override |
| public PsiImportStatement findOnDemandImportStatement(String name) { |
| while (true) { |
| Map<String, PsiImportStatement> map = myPackageNameToImportMap; |
| if (map == null) { |
| initializeMaps(); |
| } |
| else { |
| return map.get(name); |
| } |
| } |
| } |
| |
| @Override |
| public PsiImportStatementBase findSingleImportStatement(String name) { |
| while (true) { |
| Map<String, PsiImportStatementBase> map = myNameToSingleImportMap; |
| if (map == null) { |
| initializeMaps(); |
| } |
| else { |
| return map.get(name); |
| } |
| } |
| } |
| |
| @Override |
| public boolean isReplaceEquivalent(PsiImportList otherList) { |
| return getText().equals(otherList.getText()); |
| } |
| |
| private void initializeMaps() { |
| Map<String, PsiImportStatement> classNameToImportMap = new HashMap<String, PsiImportStatement>(); |
| Map<String, PsiImportStatement> packageNameToImportMap = new HashMap<String, PsiImportStatement>(); |
| Map<String, PsiImportStatementBase> nameToSingleImportMap = new HashMap<String, PsiImportStatementBase>(); |
| PsiImportStatement[] imports = getImportStatements(); |
| for (PsiImportStatement anImport : imports) { |
| String qName = anImport.getQualifiedName(); |
| if (qName == null) continue; |
| if (anImport.isOnDemand()) { |
| packageNameToImportMap.put(qName, anImport); |
| } |
| else { |
| classNameToImportMap.put(qName, anImport); |
| PsiJavaCodeReferenceElement importReference = anImport.getImportReference(); |
| if (importReference == null) continue; |
| nameToSingleImportMap.put(importReference.getReferenceName(), anImport); |
| } |
| } |
| |
| PsiImportStaticStatement[] importStatics = getImportStaticStatements(); |
| for (PsiImportStaticStatement importStatic : importStatics) { |
| if (!importStatic.isOnDemand()) { |
| String referenceName = importStatic.getReferenceName(); |
| if (referenceName != null) { |
| nameToSingleImportMap.put(referenceName, importStatic); |
| } |
| } |
| } |
| |
| myClassNameToImportMap = classNameToImportMap; |
| myPackageNameToImportMap = packageNameToImportMap; |
| myNameToSingleImportMap = nameToSingleImportMap; |
| } |
| |
| @Override |
| public void accept(@NotNull PsiElementVisitor visitor) { |
| if (visitor instanceof JavaElementVisitor) { |
| ((JavaElementVisitor)visitor).visitImportList(this); |
| } |
| else { |
| visitor.visitElement(this); |
| } |
| } |
| |
| public String toString() { |
| return "PsiImportList"; |
| } |
| } |