/** @see {@link ILocalScope#getPossibleClassesForActivationToken(String)} */ public List<String> getPossibleClassesForActivationToken(String actTok) { ArrayList<String> ret = new ArrayList<String>(); Iterator<SimpleNode> it = this.scope.topDownIterator(); if (!it.hasNext()) { return ret; } SimpleNode element = it.next(); // ok, that's the scope we have to analyze // Search for docstrings. String typeForParameter = NodeUtils.getTypeForParameterFromDocstring(actTok, element); if (typeForParameter != null) { ret.add(typeForParameter); } // Search for assert isinstance(). SequencialASTIteratorVisitor visitor = SequencialASTIteratorVisitor.create(element); Iterator<ASTEntry> iterator = visitor.getIterator(); ArrayList<Object> lst = new ArrayList<Object>(); Name nameDefinition = null; while (iterator.hasNext()) { ASTEntry entry = iterator.next(); if (entry.node.specialsAfter != null) { lst.addAll(entry.node.specialsAfter); } if (entry.node.specialsBefore != null) { lst.addAll(entry.node.specialsBefore); } if (!(entry.node instanceof Assert)) { if (entry.node instanceof Str) { lst.add(entry.node); } if (entry.node instanceof Name) { Name name = (Name) entry.node; if (name.ctx == Name.Load) { if (actTok.equals(name.id)) { nameDefinition = name; } } } continue; } Assert ass = (Assert) entry.node; if (ass.test instanceof Call) { Call call = (Call) ass.test; String rep = NodeUtils.getFullRepresentationString(call.func); if (rep == null) { continue; } Integer classIndex = ISINSTANCE_POSSIBILITIES.get(FullRepIterable.getLastPart(rep).toLowerCase()); if (classIndex != null) { if (call.args != null && (call.args.length >= Math.max(classIndex, 1))) { // in all cases, the instance is the 1st parameter. String foundActTok = NodeUtils.getFullRepresentationString(call.args[0]); if (foundActTok != null && foundActTok.equals(actTok)) { if (classIndex > 0) { exprType type = call.args[classIndex - 1]; if (type instanceof Tuple) { // case: isinstance(obj, (Class1,Class2)) Tuple tuple = (Tuple) type; for (exprType expr : tuple.elts) { addRepresentationIfPossible(ret, expr); } } else { // case: isinstance(obj, Class) addRepresentationIfPossible(ret, type); } } else { // zope case Interface.implementedBy(obj) -> Interface added ret.add(FullRepIterable.getWithoutLastPart(rep)); } } } } } } if (nameDefinition != null) { int s = lst.size(); for (int i = 0; i < s; i++) { Object object = lst.get(i); if (object instanceof commentType) { commentType commentType = (commentType) object; // according to http://sphinx-doc.org/ext/autodoc.html#directive-autoattribute, // to be a valid comment must be before the definition or in the same line. if (Math.abs(commentType.beginLine - nameDefinition.beginLine) <= 2) { if (commentType.id != null) { String trim = commentType.id.trim(); if (trim.startsWith("#")) { trim = trim.substring(1).trim(); } if (trim.startsWith(":")) { String type = NodeUtils.getTypeForParameterFromDocstring(actTok, trim.substring(1)); if (type != null) { ret.add(type); } } else if (trim.startsWith("@")) { String type = NodeUtils.getTypeForParameterFromDocstring(actTok, trim); if (type != null) { ret.add(type); } } } } } else if (object instanceof Str) { Str str = (Str) object; if (Math.abs(str.beginLine - nameDefinition.beginLine) <= 2) { if (str.s != null) { String trim = str.s.trim(); if (trim.startsWith("#")) { trim = trim.substring(1).trim(); } if (trim.startsWith(":")) { String type = NodeUtils.getTypeForParameterFromDocstring(actTok, trim.substring(1)); if (type != null) { ret.add(type); } } else if (trim.startsWith("@")) { String type = NodeUtils.getTypeForParameterFromDocstring(actTok, trim); if (type != null) { ret.add(type); } } } } } } } return ret; }
public Collection<IToken> getInterfaceForLocal( String activationToken, boolean addAttributeAccess, boolean addLocalsFromHasAttr) { Set<SourceToken> comps = new HashSet<SourceToken>(); Iterator<SimpleNode> it = this.scope.topDownIterator(); if (!it.hasNext()) { return new ArrayList<IToken>(); } SimpleNode element = it.next(); String dottedActTok = activationToken + '.'; // ok, that's the scope we have to analyze SequencialASTIteratorVisitor visitor = SequencialASTIteratorVisitor.create(element); ArrayList<Class> classes = new ArrayList<Class>(2); if (addAttributeAccess) { classes.add(Attribute.class); } if (addLocalsFromHasAttr) { classes.add(Call.class); } Iterator<ASTEntry> iterator = visitor.getIterator(classes.toArray(new Class[classes.size()])); while (iterator.hasNext()) { ASTEntry entry = iterator.next(); if (entry.node instanceof Attribute) { String rep = NodeUtils.getFullRepresentationString(entry.node); if (rep.startsWith(dottedActTok)) { rep = rep.substring(dottedActTok.length()); if (NodeUtils.isValidNameRepresentation( rep)) { // that'd be something that can happen when trying to recreate the parsing comps.add( new SourceToken( entry.node, FullRepIterable.getFirstPart(rep), "", "", "", IToken.TYPE_OBJECT_FOUND_INTERFACE)); } } } else if (entry.node instanceof Call) { Call call = (Call) entry.node; if ("hasattr".equals(NodeUtils.getFullRepresentationString(call.func)) && call.args != null && call.args.length == 2) { String rep = NodeUtils.getFullRepresentationString(call.args[0]); if (rep.equals(activationToken)) { exprType node = call.args[1]; if (node instanceof Str) { Str str = (Str) node; String attrName = str.s; if (NodeUtils.isValidNameRepresentation(attrName)) { comps.add( new SourceToken( node, attrName, "", "", "", IToken.TYPE_OBJECT_FOUND_INTERFACE)); } } } } } } return new ArrayList<IToken>(comps); }