/** * Copyright (c) 2005-2013 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 Nov 18, 2004 * * @author Fabio Zadrozny */ package org.python.pydev.editor.codecompletion.revisited; import org.eclipse.swt.graphics.Image; import org.python.pydev.core.FullRepIterable; import org.python.pydev.core.IPythonNature; import org.python.pydev.core.IToken; import org.python.pydev.core.ITypeInfo; import org.python.pydev.editor.codecompletion.PyCodeCompletionImages; import org.python.pydev.editor.codecompletion.revisited.modules.SourceToken; import org.python.pydev.parser.jython.SimpleNode; import org.python.pydev.parser.jython.ast.ClassDef; import org.python.pydev.parser.jython.ast.FunctionDef; import org.python.pydev.parser.jython.ast.decoratorsType; import org.python.pydev.parser.visitors.NodeUtils; import org.python.pydev.shared_core.string.FastStringBuffer; /** * @author Fabio Zadrozny */ public abstract class AbstractToken implements IToken { protected String rep; protected String originalRep; protected String doc; protected String args; protected String parentPackage; public int type; private boolean originalHasRep; private ITypeInfo generatorType; public final IPythonNature nature; public AbstractToken(String rep, String doc, String args, String parentPackage, int type, String originalRep, boolean originalHasRep, IPythonNature nature) { this(rep, doc, args, parentPackage, type, nature); this.originalRep = originalRep; this.originalHasRep = originalHasRep; } @Override public void setGeneratorType(ITypeInfo type) { this.generatorType = type; } @Override public ITypeInfo getGeneratorType() { return this.generatorType; } @Override public IPythonNature getNature() { return this.nature; } public AbstractToken(String rep, String doc, String args, String parentPackage, int type, IPythonNature nature) { if (rep != null) { this.rep = rep; } else { this.rep = ""; } if (args != null) { this.args = args; } else { this.args = ""; } this.originalRep = this.rep; if (doc != null) { this.doc = doc; } else { this.doc = ""; } if (parentPackage != null) { this.parentPackage = parentPackage; } else { this.parentPackage = ""; } this.type = type; this.nature = nature; } /** * @see org.python.pydev.core.IToken#getArgs() */ @Override public String getArgs() { return args; } /** * @see org.python.pydev.core.IToken#setArgs(java.lang.String) */ @Override public void setArgs(String args) { this.args = args; } /** * @see org.python.pydev.editor.javacodecompletion.IToken#getRepresentation() */ @Override public String getRepresentation() { return rep; } /** * @see org.python.pydev.core.IToken#setDocStr(java.lang.String) */ @Override public void setDocStr(String docStr) { this.doc = docStr; } /** * @see org.python.pydev.editor.javacodecompletion.IToken#getDocStr() */ @Override public String getDocStr() { return doc; } /** * @see org.python.pydev.core.IToken#getParentPackage() */ @Override public String getParentPackage() { return parentPackage; } /** * @see org.python.pydev.core.IToken#getType() */ @Override public int getType() { return type; } @Override public Image getImage() { return PyCodeCompletionImages.getImageForType(type); } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (!(obj instanceof AbstractToken)) { return false; } AbstractToken c = (AbstractToken) obj; if (c.getRepresentation().equals(getRepresentation()) == false) { return false; } if (c.getParentPackage().equals(getParentPackage()) == false) { return false; } if (c.getType() != getType()) { return false; } return true; } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return getRepresentation().hashCode() * getType(); } /** * @see java.lang.Comparable#compareTo(java.lang.Object) */ @Override public int compareTo(Object o) { AbstractToken comp = (AbstractToken) o; int thisT = getType(); int otherT = comp.getType(); if (thisT != otherT) { if (thisT == IToken.TYPE_PARAM || thisT == IToken.TYPE_LOCAL || thisT == IToken.TYPE_OBJECT_FOUND_INTERFACE) { return -1; } if (otherT == IToken.TYPE_PARAM || otherT == IToken.TYPE_LOCAL || otherT == IToken.TYPE_OBJECT_FOUND_INTERFACE) { return 1; } if (thisT == IToken.TYPE_IMPORT) { return -1; } if (otherT == IToken.TYPE_IMPORT) { return 1; } } int c = getRepresentation().compareTo(comp.getRepresentation()); if (c != 0) { return c; } c = getParentPackage().compareTo(comp.getParentPackage()); if (c != 0) { return c; } return c; } /** * @see java.lang.Object#toString() */ @Override public String toString() { if (getParentPackage() != null && getParentPackage().length() > 0) { return new FastStringBuffer(getRepresentation(), 64).append(" - ").append(getParentPackage()).toString(); } else { return getRepresentation(); } } /** * @see org.python.pydev.core.IToken#getOriginalRep(boolean) */ private String getOriginalRep(boolean decorateWithModule) { if (!decorateWithModule) { return originalRep; } String p = getParentPackage(); if (p != null && p.length() > 0) { return p + "." + originalRep; } return originalRep; } /** * Make our complete path relative to the base module. * * @see org.python.pydev.core.IToken#getAsRelativeImport(java.lang.String) */ @Override public String getAsRelativeImport(String baseModule) { String completePath = getOriginalRep(true); return makeRelative(baseModule, completePath); } @Override public String getAsAbsoluteImport() { return getAsRelativeImport("."); } /** * @param baseModule this is the 'parent package'. The path passed will be made relative to it * @param completePath this is the path that we want to make relative * @return the relative path. * * e.g.: if the baseModule is aa.xx and the completePath is aa.xx.foo.bar, this * funcion would return aa.foo.bar */ public static String makeRelative(String baseModule, String completePath) { if (baseModule == null) { return completePath; } if (completePath.startsWith(baseModule)) { String relative = completePath.substring(baseModule.length()); baseModule = FullRepIterable.headAndTail(baseModule)[0]; if (baseModule.length() == 0) { if (relative.length() > 0 && relative.charAt(0) == '.') { return relative.substring(1); } } if (relative.length() > 0 && relative.charAt(0) == '.') { return baseModule + relative; } else { return baseModule + '.' + relative; } } return completePath; } /** * @return the original representation (useful for imports) * e.g.: if it was import coilib.Exceptions as Exceptions, would return coilib.Exceptions */ @Override public String getOriginalRep() { return originalRep; } /** * @return the original representation without the actual representation (useful for imports, because * we have to look within __init__ to check if the token is defined before trying to gather modules, if * we have a name clash). * * e.g.: if it was from coilib.test import Exceptions, it would return coilib.test * * @note: if the rep is not a part of the original representation, this function will return an empty string. */ @Override public String getOriginalWithoutRep() { int i = originalRep.length() - rep.length() - 1; if (!originalHasRep) { return ""; } return i > 0 ? originalRep.substring(0, i) : ""; } @Override public int getLineDefinition() { return UNDEFINED; } @Override public int getColDefinition() { return UNDEFINED; } @Override public boolean isImport() { return false; } @Override public boolean isImportFrom() { return false; } @Override public boolean isWildImport() { return false; } @Override public boolean isString() { return false; } /** * This representation may not be accurate depending on which tokens we are dealing with. */ @Override public int[] getLineColEnd() { return new int[] { UNDEFINED, UNDEFINED }; } public static boolean isClassDef(IToken element) { if (element instanceof SourceToken) { SourceToken token = (SourceToken) element; SimpleNode ast = token.getAst(); if (ast instanceof ClassDef) { return true; } } return false; } public static boolean isFunctionDefProperty(IToken element) { if (element instanceof SourceToken) { SourceToken token = (SourceToken) element; SimpleNode ast = token.getAst(); if (ast instanceof FunctionDef) { FunctionDef functionDef = (FunctionDef) ast; decoratorsType[] decs = functionDef.decs; if (decs != null) { for (int i = 0; i < decs.length; i++) { decoratorsType dec = decs[i]; if (dec != null && dec.func != null) { if ("property".equals(NodeUtils.getRepresentationString(dec.func))) { return true; } } } } } } return false; } }