2
* Created on Dec 21, 2004
4
* @author Fabio Zadrozny
6
package org.python.pydev.editor.codecompletion.revisited.visitors;
8
import java.util.ArrayList;
11
import org.python.pydev.core.FullRepIterable;
12
import org.python.pydev.core.IToken;
13
import org.python.pydev.editor.codecompletion.revisited.modules.SourceToken;
14
import org.python.pydev.parser.jython.SimpleNode;
15
import org.python.pydev.parser.jython.ast.Compare;
16
import org.python.pydev.parser.jython.ast.If;
17
import org.python.pydev.parser.jython.ast.Import;
18
import org.python.pydev.parser.jython.ast.ImportFrom;
19
import org.python.pydev.parser.jython.ast.Name;
20
import org.python.pydev.parser.jython.ast.NameTok;
21
import org.python.pydev.parser.jython.ast.Str;
22
import org.python.pydev.parser.jython.ast.VisitorBase;
23
import org.python.pydev.parser.jython.ast.aliasType;
24
import org.python.pydev.parser.visitors.NodeUtils;
27
* @author Fabio Zadrozny
29
public abstract class AbstractVisitor extends VisitorBase{
31
public static final int GLOBAL_TOKENS = 1;
33
public static final int WILD_MODULES = 2;
35
public static final int ALIAS_MODULES = 3;
37
public static final int MODULE_DOCSTRING = 4;
39
public static final int INNER_DEFS = 5;
41
protected List<IToken> tokens = new ArrayList<IToken>();
44
* Module being visited.
46
protected String moduleName;
49
* Adds a token with a docstring.
53
protected void addToken(SimpleNode node) {
55
SourceToken t = makeToken(node, moduleName);
64
public static SourceToken makeToken(SimpleNode node, String moduleName) {
65
return new SourceToken(node, NodeUtils.getRepresentationString(node), NodeUtils.getNodeArgs(node), NodeUtils.getNodeDocString(node), moduleName);
69
* same as make token, but returns the full representation for a token, instead of just a 'partial' name
71
public static SourceToken makeFullNameToken(SimpleNode node, String moduleName) {
72
return new SourceToken(node, NodeUtils.getFullRepresentationString(node), NodeUtils.getNodeArgs(node), NodeUtils.getNodeDocString(node), moduleName);
77
* This function creates source tokens from a wild import node.
79
* @param node the import node
80
* @param tokens OUT used to add the source token
81
* @param moduleName the module name
83
* @return the tokens list passed in or the created one if it was null
85
public static IToken makeWildImportToken(ImportFrom node, List<IToken> tokens, String moduleName) {
87
tokens = new ArrayList<IToken>();
89
SourceToken sourceToken = null;
90
if(isWildImport(node)){
91
sourceToken = new SourceToken(node, ((NameTok)node.module).id, "", "", moduleName);
92
tokens.add(sourceToken);
97
public static List<IToken> makeImportToken(SimpleNode node, List<IToken> tokens, String moduleName, boolean allowForMultiple) {
98
if(node instanceof Import){
99
return makeImportToken((Import)node, tokens, moduleName, allowForMultiple);
101
if(node instanceof ImportFrom){
102
ImportFrom i = (ImportFrom) node;
104
makeWildImportToken(i, tokens, moduleName);
107
return makeImportToken((ImportFrom)node, tokens, moduleName, allowForMultiple);
110
throw new RuntimeException("Unable to create token for the passed import ("+node+")");
114
* This function creates source tokens from an import node.
116
* @param node the import node
117
* @param moduleName the module name
118
* @param tokens OUT used to add the source tokens (may create many from a single import)
119
* @param allowForMultiple is used to indicate if an import in the format import os.path should generate one token for os
120
* and another for os.path or just one for both with os.path
122
* @return the tokens list passed in or the created one if it was null
124
public static List<IToken> makeImportToken(Import node, List<IToken> tokens, String moduleName, boolean allowForMultiple) {
125
aliasType[] names = node.names;
126
return makeImportToken(node, tokens, names, moduleName, "", allowForMultiple);
130
* The same as above but with ImportFrom
132
public static List<IToken> makeImportToken(ImportFrom node, List<IToken> tokens, String moduleName, boolean allowForMultiple) {
133
aliasType[] names = node.names;
134
String importName = ((NameTok)node.module).id;
136
return makeImportToken(node, tokens, names, moduleName, importName, allowForMultiple);
142
private static List<IToken> makeImportToken(SimpleNode node, List<IToken> tokens, aliasType[] names, String module, String initialImportName, boolean allowForMultiple) {
144
tokens = new ArrayList<IToken>();
147
if(initialImportName.length() > 0){
148
initialImportName = initialImportName+".";
151
for (int i = 0; i < names.length; i++) {
152
aliasType aliasType = names[i];
155
String original = ((NameTok)aliasType.name).id;
157
if(aliasType.asname != null){
158
name = ((NameTok)aliasType.asname).id;
162
FullRepIterable iterator = new FullRepIterable(original);
163
for (String rep : iterator) {
164
SourceToken sourceToken = new SourceToken(node, rep, "", "", module, initialImportName+rep);
165
tokens.add(sourceToken);
168
SourceToken sourceToken = new SourceToken(node, name, "", "", module, initialImportName+original);
169
tokens.add(sourceToken);
177
public static boolean isWildImport(SimpleNode node) {
178
if (node instanceof ImportFrom) {
179
ImportFrom n = (ImportFrom) node;
180
return isWildImport(n);
185
public static boolean isWildImport(IToken generator) {
186
if (generator instanceof SourceToken) {
187
SourceToken t = (SourceToken) generator;
188
return isWildImport(t.getAst());
194
* @param node the node to analyze
195
* @return whether it is a wild import
197
public static boolean isWildImport(ImportFrom node) {
198
return node.names.length == 0;
202
* @param node the node to analyze
203
* @return whether it is an alias import
205
public static boolean isAliasImport(ImportFrom node) {
206
return node.names.length > 0;
209
public List<IToken> getTokens() {
214
* This method transverses the ast and returns a list of found tokens.
222
public static IToken[] getTokens(SimpleNode ast, int which, String moduleName) {
223
AbstractVisitor modelVisitor;
224
if(which == INNER_DEFS){
225
modelVisitor = new InnerModelVisitor(moduleName);
227
modelVisitor = new GlobalModelVisitor(which, moduleName);
232
ast.accept(modelVisitor);
233
} catch (Exception e) {
234
throw new RuntimeException(e);
236
return (SourceToken[]) modelVisitor.tokens.toArray(new SourceToken[0]);
238
return new SourceToken[0];
245
public static Str isIfMAinNode(If node) {
246
if (node.test instanceof Compare) {
247
Compare compareNode = (Compare)node.test;
248
// handcrafted structure walking
249
if (compareNode.left instanceof Name
250
&& ((Name)compareNode.left).id.equals("__name__")
251
&& compareNode.ops != null
252
&& compareNode.ops.length == 1
253
&& compareNode.ops[0] == Compare.Eq){
255
if ( compareNode.comparators != null
256
&& compareNode.comparators.length == 1
257
&& compareNode.comparators[0] instanceof Str
258
&& ((Str)compareNode.comparators[0]).s.equals("__main__")){
259
return (Str)compareNode.comparators[0];