/******************************************************************************* * Copyright (c) 2005, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.wst.jsdt.internal.core; import java.util.HashMap; import java.util.Map; import org.eclipse.wst.jsdt.core.IJavaScriptElement; import org.eclipse.wst.jsdt.core.IJavaScriptUnit; import org.eclipse.wst.jsdt.core.IPackageFragmentRoot; import org.eclipse.wst.jsdt.core.JavaScriptModelException; import org.eclipse.wst.jsdt.internal.core.util.HashtableOfArrayToObject; public class LookupScopeElementInfo extends PackageFragmentRootInfo { private JavaProject javaProject; private IPackageFragmentRoot[] rootsInScope; private LookupCache cache; //public static final String[] SYSTEM_LIBRARIES = {"system.js"}; /* places imports in the document scope before the classpath entries */ private static final boolean LOOKUP_LOCAL_SCOPE_FIRST = false; static class LookupCache { LookupCache(IPackageFragmentRoot[] allPkgFragmentRootsCache, HashtableOfArrayToObject allPkgFragmentsCache, HashtableOfArrayToObject isPackageCache, Map rootToResolvedEntries) { this.allPkgFragmentRootsCache = allPkgFragmentRootsCache; this.allPkgFragmentsCache = allPkgFragmentsCache; this.isPackageCache = isPackageCache; this.rootToResolvedEntries = rootToResolvedEntries; } /* * A cache of all package fragment roots of this project. */ public IPackageFragmentRoot[] allPkgFragmentRootsCache; /* * A cache of all package fragments in this project. * (a map from String[] (the package name) to IPackageFragmentRoot[] (the package fragment roots that contain a package fragment with this name) */ public HashtableOfArrayToObject allPkgFragmentsCache; /* * A set of package names (String[]) that are known to be packages. */ public HashtableOfArrayToObject isPackageCache; public Map rootToResolvedEntries; } public IPackageFragmentRoot[] getAllRoots() { if(LOOKUP_LOCAL_SCOPE_FIRST) return getAllRootsLocalFirst(); return getAllRootsGlobalFirst(); } private IPackageFragmentRoot[] getAllRootsGlobalFirst() { IPackageFragmentRoot[] projectRoots = new IPackageFragmentRoot[0]; int lastGood = 0; try { projectRoots = javaProject.getPackageFragmentRoots(); for(int i =0;i<projectRoots.length;i++) { if(projectRoots[i].isLanguageRuntime()) { projectRoots[lastGood++]=projectRoots[i]; } } } catch (JavaScriptModelException ex) { projectRoots = new IPackageFragmentRoot[0]; } IPackageFragmentRoot[] allRoots = new IPackageFragmentRoot[lastGood + rootsInScope.length ]; System.arraycopy(projectRoots, 0, allRoots, 0, lastGood); System.arraycopy(rootsInScope, 0, allRoots, lastGood, rootsInScope.length); return allRoots; } private IPackageFragmentRoot[] getAllRootsLocalFirst() { IPackageFragmentRoot[] projectRoots = new IPackageFragmentRoot[0]; int lastGood = 0; try { projectRoots = javaProject.getPackageFragmentRoots(); for(int i =0;i<projectRoots.length;i++) { if(projectRoots[i].isLanguageRuntime()) { projectRoots[lastGood++]=projectRoots[i]; } } } catch (JavaScriptModelException ex) { projectRoots = new IPackageFragmentRoot[0]; } IPackageFragmentRoot[] allRoots = new IPackageFragmentRoot[lastGood + rootsInScope.length ]; System.arraycopy(rootsInScope, 0, allRoots, 0, rootsInScope.length); System.arraycopy(projectRoots, 0, allRoots, rootsInScope.length, lastGood); return allRoots; } public LookupScopeElementInfo(JavaProject project,IPackageFragmentRoot[] rootsInScope){ this.javaProject = project; this.rootsInScope = rootsInScope; } NameLookup newNameLookup(IJavaScriptUnit[] workingCopies) { BuildLookupScopeCache(getAllRoots()); return new NameLookup(cache.allPkgFragmentRootsCache, cache.allPkgFragmentsCache, workingCopies, cache.rootToResolvedEntries); } public LookupCache BuildLookupScopeCache(IPackageFragmentRoot[] rootsInScope) { Map reverseMap = new HashMap(3); // IPackageFragmentRoot[] roots=null; // // for(int i = 0;i<rootsInScope.length;i++) { // try { // // IIncludePathEntry entry = javaProject.getClasspathEntryFor(rootsInScope[i].getPath()); // reverseMap.put(rootsInScope[i],entry); // } catch (JavaScriptModelException ex) { // // TODO Auto-generated catch block // ex.printStackTrace(); // } // // } // try { // roots = javaProject.getAllPackageFragmentRoots(reverseMap); // } catch (JavaScriptModelException e) { // // project does not exist: cannot happen since this is the info of the project // roots = new IPackageFragmentRoot[0]; // reverseMap.clear(); // } HashtableOfArrayToObject fragmentsCache = new HashtableOfArrayToObject(); HashtableOfArrayToObject isPackageCache = new HashtableOfArrayToObject(); for (int i = 0, length = rootsInScope.length; i < length; i++) { IPackageFragmentRoot root = rootsInScope[i]; IJavaScriptElement[] frags = null; try { if(root instanceof DocumentContextFragmentRoot) { LibraryFragmentRootInfo info = new LibraryFragmentRootInfo(); ((DocumentContextFragmentRoot) root).computeChildren(info, new HashMap()); frags = info.children; }else if (root instanceof LibraryFragmentRoot) { LibraryFragmentRootInfo info = new LibraryFragmentRootInfo(); ((LibraryFragmentRoot) root).computeChildren(info, new HashMap()); frags = info.children; // } else if (root.isArchive() && !root.isOpen()) { // JarPackageFragmentRootInfo info = new JarPackageFragmentRootInfo(); // ((JarPackageFragmentRoot) root).computeChildren(info, new HashMap()); // frags = info.children; } else if (root instanceof PackageFragmentRoot) { PackageFragmentRootInfo info = new PackageFragmentRootInfo(); ((PackageFragmentRoot) root).computeChildren(info, new HashMap()); frags = info.children; }else frags = root.getChildren(); } catch (JavaScriptModelException e) { // root doesn't exist: ignore continue; } for (int j = 0, length2 = frags.length; j < length2; j++) { PackageFragment fragment= (PackageFragment) frags[j]; /* Keep folders off the classpath */ //if(fragment.getPath().getFileExtension()==null || !fragment.getPath().getFileExtension().equals(".js")) continue; String[] pkgName = fragment.names; Object existing = fragmentsCache.get(pkgName); if (existing == null) { fragmentsCache.put(pkgName, root); // cache whether each package and its including packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161) // are actual packages addNames(pkgName, isPackageCache); } else { if (existing instanceof PackageFragmentRoot) { fragmentsCache.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root}); } else { IPackageFragmentRoot[] entry= (IPackageFragmentRoot[]) existing; IPackageFragmentRoot[] copy= new IPackageFragmentRoot[entry.length + 1]; System.arraycopy(entry, 0, copy, 0, entry.length); copy[entry.length]= root; fragmentsCache.put(pkgName, copy); } } } } cache = new LookupCache(rootsInScope, fragmentsCache, isPackageCache, reverseMap); return cache; } public static void addNames(String[] name, HashtableOfArrayToObject set) { set.put(name, name); int length = name.length; for (int i = length-1; i > 0; i--) { String[] superName = new String[i]; System.arraycopy(name, 0, superName, 0, i); set.put(superName, superName); } } }