/** * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ /* * Created on 27/07/2005 */ package com.python.pydev.analysis.visitors; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.python.pydev.core.IToken; import org.python.pydev.core.structure.FastStack; import org.python.pydev.parser.jython.ast.TryExcept; import org.python.pydev.parser.jython.ast.excepthandlerType; import org.python.pydev.parser.visitors.NodeUtils; import com.aptana.shared_core.string.FastStringBuffer; import com.aptana.shared_core.structure.Tuple; public final class ScopeItems { /** * This is the class that is used to wrap the try..except node (so that we can add additional info to it). */ public static class TryExceptInfo { public TryExcept except; private Map<String, List<Found>> importsMapInTryExcept = new HashMap<String, List<Found>>(); public TryExceptInfo(TryExcept except) { this.except = except; } /** * When we add a new import found within a try..except ImportError, we mark the previous import * with the same name as used (as this one will redefine it in an expected way). */ public void addFoundImportToTryExcept(Found found) { if (!found.isImport()) { return; } String rep = found.getSingle().generator.getRepresentation(); List<Found> importsListInTryExcept = importsMapInTryExcept.get(rep); if (importsListInTryExcept == null) { importsListInTryExcept = new ArrayList<Found>(); importsMapInTryExcept.put(rep, importsListInTryExcept); } else if (importsListInTryExcept.size() > 0) { importsListInTryExcept.get(importsListInTryExcept.size() - 1).setUsed(true); } importsListInTryExcept.add(found); } } /** * @return the TryExcept from a try..except ImportError if we are currently within such a scope * (otherwise will return null;. */ public ScopeItems.TryExceptInfo getTryExceptImportError() { for (ScopeItems.TryExceptInfo except : getCurrTryExceptNodes()) { for (excepthandlerType handler : except.except.handlers) { if (handler.type != null) { String rep = NodeUtils.getRepresentationString(handler.type); if (rep != null && rep.equals("ImportError")) { return except; } } } } return null; } private final Map<String, List<Found>> m = new HashMap<String, List<Found>>(); /** * Stack for names that should not generate warnings, such as builtins, method names, etc. */ public Map<String, Tuple<IToken, Found>> namesToIgnore = new HashMap<String, Tuple<IToken, Found>>(); public int ifSubScope = 0; public FastStack<TryExceptInfo> tryExceptSubScope = new FastStack<TryExceptInfo>(10); private int scopeId; private int scopeType; public ScopeItems(int scopeId, int scopeType) { this.scopeId = scopeId; this.scopeType = scopeType; } public Found getLastAppearance(String rep) { List<Found> foundItems = m.get(rep); if (foundItems == null || foundItems.size() == 0) { return null; } return foundItems.get(foundItems.size() - 1); } public void setAllUsed() { for (List<Found> list : m.values()) { int len = list.size(); for (int i = 0; i < len; i++) { list.get(i).setUsed(true); } } } /** * @return a list with all the found items in this scope */ public Collection<List<Found>> getAll() { return m.values(); } /** * @return all the found items that match the given representation. */ public List<Found> getAll(String rep) { List<Found> r = m.get(rep); if (r == null) { return new ArrayList<Found>(0); } return r; } public void put(String rep, Found found) { List<Found> foundItems = m.get(rep); if (foundItems == null) { foundItems = new ArrayList<Found>(); m.put(rep, foundItems); } foundItems.add(found); } public void addIfSubScope() { ifSubScope++; } public void removeIfSubScope() { ifSubScope--; } public void addTryExceptSubScope(TryExcept node) { tryExceptSubScope.push(new TryExceptInfo(node)); } public void removeTryExceptSubScope() { tryExceptSubScope.pop(); } public FastStack<TryExceptInfo> getCurrTryExceptNodes() { return tryExceptSubScope; } public boolean getIsInSubSubScope() { return ifSubScope != 0 || tryExceptSubScope.size() != 0; } public boolean getIsInIfSubScope() { return ifSubScope != 0; } /** * @return Returns the scopeId. */ public int getScopeId() { return scopeId; } /** * @return Returns the scopeType. */ public int getScopeType() { return scopeType; } @Override public String toString() { FastStringBuffer buffer = new FastStringBuffer(); buffer.append("ScopeItem (type:"); buffer.append(Scope.getScopeTypeStr(scopeType)); buffer.append(")\n"); for (Map.Entry<String, List<Found>> entry : m.entrySet()) { buffer.append(entry.getKey()); buffer.append(": contains "); buffer.append(entry.getValue().toString()); buffer.append("\n"); } return buffer.toString(); } /** * @return all the used items */ public List<Tuple<String, Found>> getUsedItems() { ArrayList<Tuple<String, Found>> found = new ArrayList<Tuple<String, Found>>(); for (Map.Entry<String, List<Found>> entry : m.entrySet()) { for (Found f : entry.getValue()) { if (f.isUsed()) { found.add(new Tuple<String, Found>(entry.getKey(), f)); } } } return found; } }