@SuppressWarnings("unchecked") private static ListASTNode<? extends ASTNode> searchList(ASTNode top) { if (top instanceof ListASTNode) return (ListASTNode<? extends ASTNode>) top; ASTNode parent = top.getParent(); if (parent == null) return null; return searchList(parent); }
/** * Searches documentation for <code>field</code>. * * @param field the identifier of some field * @param region additional information about the document * @return the documentation or <code>null</code> */ protected String getFieldDocumentation(Identifier field, DocumentRegionInformation region) { ASTNode node = field; while (node != null) { if (node instanceof FunctionDefinition) { FunctionDefinition definition = (FunctionDefinition) node; FieldModelNode fieldNode = definition.resolveNode(); if (fieldNode != null) { Name[] arguments = fieldNode.getArgumentNames(); if (arguments != null) { for (Name name : arguments) { if (name != null) { if (name.toIdentifier().equals(field.getName())) { NesCDocComment comment = getFunctionDocumentation(definition, region); if (comment == null) return null; return comment.getAnalysis().getParameterDescription(field.getName()); } } } } } } NesCDocComment[] comments = node.getComments(); if (comments != null) { for (int i = comments.length - 1; i >= 0; i--) { String documentation = comments[i].getAnalysis().getParameterDescription(field.getName()); if (documentation != null) return documentation; } } node = node.getParent(); } return null; }
/** * Method to retrieve as much as possible from the generated Abstract Syntax Tree even if the * parser stopped with a heavy error. * * @param result the result of the parser * @param stack the parsers stack * @param remaining the remaining errors on the parser * @return a node that somehow combines all remaining elements */ public static ASTNode parseAST(Symbol result, Stack<?> stack, List<ErrorASTNode> remaining) { ASTNode root; if (result != null && result.value instanceof ASTNode) { root = (ASTNode) result.value; } else { root = new TranslationUnit(); } while (root.getParent() != null) root = root.getParent(); // search for nodes that are still on the stack (but should not be there) List<ASTNode> begin = new ArrayList<ASTNode>(); for (int i = 0, n = stack.size() - 1; i < n; i++) { Symbol next = (Symbol) stack.get(i); if (next.value instanceof ASTNode) { if (next.value != root) { begin.add((ASTNode) next.value); } } } if (!begin.isEmpty()) { // the stack was not built correct, try put these things together begin.add(root); Collections.sort( begin, new Comparator<ASTNode>() { public int compare(ASTNode a, ASTNode b) { if (a == b) return 0; Range rangeA = a.getRange(); Range rangeB = b.getRange(); if (rangeA.getLeft() < rangeB.getLeft()) return -1; if (rangeA.getLeft() > rangeB.getLeft()) return 1; if (rangeA.getRight() < rangeB.getRight()) return -1; if (rangeA.getRight() > rangeB.getRight()) return 1; return 0; } }); root = begin.get(begin.size() - 1); for (int i = begin.size() - 2; i >= 0; i--) { ASTNode next = begin.get(i); root = merge(next, root); } } if (!remaining.isEmpty()) { if (!(root instanceof ListASTNode)) { root = new ListErrorASTNode(root); } ListASTNode<?> list = (ListASTNode<?>) root; for (ErrorASTNode error : remaining) list.addError(error); } return root; }
private static ASTNode parent(ASTNode node) { while (node.getParent() != null) node = node.getParent(); return node; }