Java Code Examples for org.netbeans.modules.csl.spi.ParserResult

The following examples show how to use org.netbeans.modules.csl.spi.ParserResult. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: netbeans   Source File: YamlKeystrokeHandler.java    License: Apache License 2.0 6 votes vote down vote up
@Override
public List<OffsetRange> findLogicalRanges(ParserResult info, int caretOffset) {
    YamlParserResult result = (YamlParserResult) info;
    if (result == null) {
        return Collections.emptyList();
    }

    List<? extends StructureItem> items = result.getItems();
    if (items.isEmpty()) {
        return Collections.emptyList();
    }

    List<OffsetRange> ranges = new ArrayList<OffsetRange>();
    for (StructureItem item : items) {
        addRanges(ranges, caretOffset, item);
    }

    Collections.reverse(ranges);
    Document doc = info.getSnapshot().getSource().getDocument(false);
    if (doc != null) {
        ranges.add(new OffsetRange(0, doc.getLength()));
    }

    return ranges;
}
 
Example 2
Source Project: netbeans   Source File: GsfHintsManager.java    License: Apache License 2.0 6 votes vote down vote up
public RuleContext createRuleContext (ParserResult parserResult, Language language, int caretOffset, int selectionStart, int selectionEnd) {
        RuleContext context = provider.createRuleContext();
        context.manager = this;
        context.parserResult = parserResult;
        context.caretOffset = caretOffset;
        context.selectionStart = selectionStart;
        context.selectionEnd = selectionEnd;
        context.doc = (BaseDocument) parserResult.getSnapshot().getSource().getDocument(false);
        if (context.doc == null) {
            // Document closed
            return null;
        }
        
// XXX: parsingapi
//        Collection<? extends ParserResult> embeddedResults = info.getEmbeddedResults(language.getMimeType());
//        context.parserResults = embeddedResults != null ? embeddedResults : Collections.EMPTY_LIST;
//        if (context.parserResults.size() > 0) {
//            context.parserResult = embeddedResults.iterator().next();
//        }

        return context;
    }
 
Example 3
Source Project: netbeans   Source File: CslTestBase.java    License: Apache License 2.0 6 votes vote down vote up
protected void checkTypes(final String relFilePath, final String caretLine) throws Exception {
    Source testSource = getTestSource(getTestFile(relFilePath));

    if (caretLine != null) {
        int caretOffset = getCaretOffset(testSource.createSnapshot().getText().toString(), caretLine);
        enforceCaretOffset(testSource, caretOffset);
    }

    ParserManager.parse(Collections.singleton(testSource), new UserTask() {
        public @Override void run(ResultIterator resultIterator) throws Exception {
            Parser.Result r = resultIterator.getParserResult();
            assertTrue(r instanceof ParserResult);
            ParserResult pr = (ParserResult) r;

            List<Object> nodes = new ArrayList<Object>();
            Map<Object,String> types = new HashMap<Object,String>();
            Map<Object,OffsetRange> positions = new HashMap<Object,OffsetRange>();
            initializeTypeNodes(pr, nodes, positions, types);

            String annotatedSource = annotateTypes(nodes, positions, types, pr);
            assertDescriptionMatches(relFilePath, annotatedSource, false, ".types");
        }
    });
}
 
Example 4
Source Project: netbeans   Source File: JQueryCodeCompletion.java    License: Apache License 2.0 6 votes vote down vote up
private String findFunctionName(ParserResult parserResult, int offset) {
    TokenSequence<? extends JsTokenId> ts = LexUtilities.getJsTokenSequence(parserResult.getSnapshot().getTokenHierarchy(), offset);
    if (ts == null) {
        return null;
    }
    ts.move(offset);
    if (!(ts.moveNext() && ts.movePrevious())) {
        return null;
    }
    Token<? extends JsTokenId> token = LexUtilities.findNext(ts, Arrays.asList(JsTokenId.WHITESPACE));
    while(token.id() != JsTokenId.EOL && token.id() != JsTokenId.BRACKET_LEFT_PAREN) {
        if (token.id() == JsTokenId.OPERATOR_DOT) {
            // we are not inside ()
            return null;
        }
        token = LexUtilities.findNext(ts, Arrays.asList(JsTokenId.WHITESPACE));
    }
    if (token.id() == JsTokenId.BRACKET_LEFT_PAREN && ts.movePrevious()) {
        token = LexUtilities.findNext(ts, Arrays.asList(JsTokenId.WHITESPACE));
        if (token.id() == JsTokenId.IDENTIFIER){
            return token.text().toString();
        }
    }
    return null;
}
 
Example 5
Source Project: netbeans   Source File: JQueryCodeCompletion.java    License: Apache License 2.0 6 votes vote down vote up
private Collection<String> getCSSClasses(String classPrefix, ParserResult parserResult) {
    FileObject fo = parserResult.getSnapshot().getSource().getFileObject();
    if(fo == null) {
        return Collections.emptyList();
    }
    Project project = FileOwnerQuery.getOwner(fo);
    HashSet<String> unique = new HashSet<String>();
    try {
        CssIndex cssIndex = CssIndex.create(project);
        Map<FileObject, Collection<String>> findIdsByPrefix = cssIndex.findClassesByPrefix(classPrefix);

        for (Collection<String> ids : findIdsByPrefix.values()) {
            for (String id : ids) {
                unique.add(id);
            }
        }
    } catch (IOException ex) {
        Exceptions.printStackTrace(ex);
    }
    return unique;

}
 
Example 6
Source Project: netbeans   Source File: ElementScanningTask.java    License: Apache License 2.0 6 votes vote down vote up
public static List<? extends StructureItem> findCachedStructure(Snapshot s, Parser.Result r) {
    if (!(r instanceof ParserResult)) {
        return null;
    }
    Reference<ResultStructure> previousRef;
    previousRef = lastResults.get(s);
    if (previousRef == null) {
        return null;
    }
    ResultStructure cached = previousRef.get();
    if (cached == null || cached.result != r) {
        // remove from cache:
        lastResults.remove(s);
        return null;
    }
    return cached.structure;
}
 
Example 7
Source Project: netbeans   Source File: PhpCommentGenerator.java    License: Apache License 2.0 6 votes vote down vote up
public ScannerImpl(ParserResult info, FunctionDeclaration decl) {
    if (info instanceof PHPParseResult) {
        PHPParseResult parseResult = (PHPParseResult) info;
        Model model = parseResult.getModel();
        final VariableScope variableScope = model.getVariableScope(decl.getEndOffset() - 1);
        NamespaceScope namespaceScope = ModelUtils.getNamespaceScope(model.getFileScope(), decl.getEndOffset() - 1);
        if (namespaceScope != null) {
            declaredUses = namespaceScope.getAllDeclaredSingleUses();
        }
        if (variableScope instanceof FunctionScope) {
            fnc = (FunctionScope) variableScope;
            declaredVariables.addAll(fnc.getDeclaredVariables());
        } else {
            fnc = null;
        }
    } else {
        fnc = null;
    }
    this.decl = decl;
}
 
Example 8
Source Project: netbeans   Source File: GsfHintsProvider.java    License: Apache License 2.0 6 votes vote down vote up
public @Override void run(ParserResult result, SchedulerEvent event) {
    final Document doc = getDocument();
    if (doc == null) {
        LOG.log(Level.INFO, "SemanticHighlighter: Cannot get document!");
        return ;
    }
    SpiSupportAccessor.getInstance().setCancelSupport(cancel);
    try {
        ParserManager.parse(Collections.singleton(result.getSnapshot().getSource()), new UserTask() {
            public @Override void run(ResultIterator resultIterator) throws ParseException {
                refreshErrors(resultIterator);
            }

        });
    } catch (ParseException e) {
        LOG.log(Level.WARNING, null, e);
    } finally {
        SpiSupportAccessor.getInstance().removeCancelSupport(cancel);
    }
}
 
Example 9
Source Project: netbeans   Source File: JadeStructureScanner.java    License: Apache License 2.0 5 votes vote down vote up
private void appendFold(ParserResult info, Map<String, List<OffsetRange>> folds, String kind, int startOffset, int endOffset) {
    if (startOffset >= 0 && endOffset >= startOffset) {
        if (info.getSnapshot().getText().subSequence(startOffset, endOffset).toString().indexOf('\n') > -1) {
            getRanges(folds, kind).add(new OffsetRange(startOffset, endOffset));
        }   
    }
}
 
Example 10
Source Project: netbeans   Source File: OverridingMethodsImpl.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * @return the inheritedByTypes
 */
private Set<TypeElement> getInheritedByTypes(final ParserResult info, final TypeScope type) {
    final String signature = type.getIndexSignature();
    if (signature != null && !signature.equals(classSignatureForInheritedByTypes)) {
        Index index = ElementQueryFactory.getIndexQuery(info);
        inheritedByTypes = index.getInheritedByTypes(type);
    }
    classSignatureForInheritedByTypes = signature;
    return inheritedByTypes;
}
 
Example 11
Source Project: netbeans   Source File: JadeCodeCompletion.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public String getPrefix(ParserResult info, int caretOffset, boolean upToOffset) {
    String prefix = null;

    BaseDocument doc = (BaseDocument) info.getSnapshot().getSource().getDocument(false);
    if (doc == null) {
        return null;
    }

    //caretOffset = info.getSnapshot().getEmbeddedOffset(caretOffset);
    TokenSequence<? extends JadeTokenId> ts = info.getSnapshot().getTokenHierarchy().tokenSequence(JadeTokenId.jadeLanguage());
    if (ts == null) {
        return null;
    }

    int offset = info.getSnapshot().getEmbeddedOffset(caretOffset);
    ts.move(offset);

    if (!ts.moveNext() && !ts.movePrevious()) {
        return null;
    }
    
    if (ts.offset() == offset) {
        // We're looking at the offset to the RIGHT of the caret
        // and here I care about what's on the left
        ts.movePrevious();
    }

    Token<? extends JadeTokenId> token = ts.token();
    if (token.id() == JadeTokenId.TAG || token.id().isKeyword()) {
        prefix = token.text().toString();
        if (upToOffset) {
            if (offset - ts.offset() >= 0) {
                prefix = prefix.substring(0, offset - ts.offset());
            }
        }
    }
    return prefix;
}
 
Example 12
Source Project: netbeans   Source File: BreadCrumbsTask.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public void run(final ParserResult result, final SchedulerEvent event) {
    runWithCancelService(new Runnable() {
        @Override
        public void run() {
            resume();
            final long id = requestId.incrementAndGet();

            final Document doc = result.getSnapshot().getSource().getDocument(false);

            if (doc == null || !BreadcrumbsController.areBreadCrumsEnabled(doc)) return ;

            final int caret;

            if (event instanceof CursorMovedSchedulerEvent) {
                caret = ((CursorMovedSchedulerEvent) event).getCaretOffset();
            } else {
                //XXX: outside AWT!
                JTextComponent c = EditorRegistry.focusedComponent();

                if (c != null && c.getDocument() == doc)
                    caret = c.getCaretPosition();
                else
                    caret = (-1);
            }

            if (caret == (-1)) return ;

            final StructureItem structureRoot = computeStructureRoot(result.getSnapshot().getSource());

            if (structureRoot == null) return ;

            WORKER.post(new Runnable() {
                @Override public void run() {
                    selectNode(doc, structureRoot, id, caret);
                }
            });
        }
    });
}
 
Example 13
Source Project: netbeans   Source File: DeclarationFinderImpl.java    License: Apache License 2.0 5 votes vote down vote up
public static DeclarationLocation findDeclarationImpl(ParserResult info, int caretOffset) {
    if (!(info instanceof PHPParseResult)) {
        return DeclarationLocation.NONE;
    }
    PHPParseResult result = (PHPParseResult) info;
    final Model model = result.getModel(Model.Type.COMMON);
    OccurencesSupport occurencesSupport = model.getOccurencesSupport(caretOffset);
    Occurence underCaret = occurencesSupport.getOccurence();
    return findDeclarationImpl(underCaret, info);
}
 
Example 14
Source Project: netbeans   Source File: PHPCodeCompletion.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public ParameterInfo parameters(final ParserResult info, final int caretOffset, CompletionProposal proposal) {
    final org.netbeans.modules.php.editor.model.Model model = ((PHPParseResult) info).getModel();
    ParameterInfoSupport infoSupport = model.getParameterInfoSupport(caretOffset);
    ParameterInfo parameterInfo = infoSupport.getParameterInfo();
    return parameterInfo == null ? ParameterInfo.NONE : parameterInfo;
}
 
Example 15
Source Project: netbeans   Source File: CompletionContext.java    License: Apache License 2.0 5 votes vote down vote up
private AstPath getPath(ParserResult parseResult, BaseDocument doc, int astOffset) {
    ASTNode root = ASTUtils.getRoot(parseResult);

    // in some cases we can not repair the code, therefore root == null
    // therefore we can not complete. See # 131317
    if (root == null) {
        return null;
    }
    return new AstPath(root, astOffset, doc);
}
 
Example 16
Source Project: netbeans   Source File: TwigCompletionHandler.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public Documentation documentElement(ParserResult parserResult, ElementHandle elementHandle, Callable<Boolean> cancel) {
    Documentation result = null;
    if (elementHandle instanceof TwigElement) {
        result = Documentation.create(((TwigElement) elementHandle).getDocumentation().asText(), documentationUrl);
    }
    return result;
}
 
Example 17
Source Project: netbeans   Source File: HtmlRenameHandler.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public boolean isRenameAllowed(ParserResult info, int caretOffset, String[] explanationRetValue) {
    int astCaretOffset = info.getSnapshot().getEmbeddedOffset(caretOffset);
    if (astCaretOffset == -1) {
        return false;
    }

    HtmlParserResult result = (HtmlParserResult) info;
    Element node = result.findByPhysicalRange(astCaretOffset, true);

    if (node == null) {
        return false;
    }

    switch (node.type()) {
        case OPEN_TAG:
            OpenTag ot = (OpenTag)node;
            //enable only if the caret is in the tag name
            int from = node.from();
            int to = from + 1 + ot.name().length() ; //"<" + "body" length
            return astCaretOffset >= from && astCaretOffset <= to;
        case CLOSE_TAG:
            return true;
    }

    return false;

}
 
Example 18
Source Project: netbeans   Source File: TableGenerator.java    License: Apache License 2.0 5 votes vote down vote up
private String findConnVariableInScope() {
    final List<String> connVariables = new ArrayList<>();

    try {
        ParserManager.parse(Collections.singleton(Source.create(component.getDocument())), new UserTask() {

            @Override
            public void run(ResultIterator resultIterator) throws Exception {
                ParserResult info = (ParserResult) resultIterator.getParserResult();
                if (info != null) {
                    ASTNodeUtilities.getVariablesInScope(info, component.getCaretPosition(), new VariableAcceptor() {

                        @Override
                        public boolean acceptVariable(String variableName) {
                            if (variableName.contains("conn")) { // NOI18N
                                connVariables.add(variableName);
                            }
                            return false;
                        }
                    });
                }
            }
        });
    } catch (ParseException ex) {
        Exceptions.printStackTrace(ex);
        return null;
    }

    if (connVariables.contains("conn")) { // NOI18N
        return "conn"; // NOI18N
    }
    if (connVariables.contains("connection")) { // NOI18N
        return "connection"; // NOI18N
    }
    for (String connVariable : connVariables) {
        return connVariable;
    }
    return null;
}
 
Example 19
Source Project: netbeans   Source File: InstantRenamerImpl.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public Set<OffsetRange> getRenameRegions(ParserResult info, int caretOffset) {
    Set<OffsetRange> retval = new HashSet<>();
    for (Occurence occurence : allOccurences) {
        retval.add(occurence.getOccurenceRange());
    }
    allOccurences.clear();
    return retval;
}
 
Example 20
Source Project: netbeans   Source File: PHPCodeCompletion.java    License: Apache License 2.0 5 votes vote down vote up
private int findBaseNamespaceEnd(ParserResult info, int caretOffset) {
    TokenHierarchy<?> th = info.getSnapshot().getTokenHierarchy();
    assert th != null;
    TokenSequence<PHPTokenId> tokenSequence = LexUtilities.getPHPTokenSequence(th, caretOffset);
    assert tokenSequence != null;
    tokenSequence.move(caretOffset);
    final boolean moveNextSucces = tokenSequence.moveNext();
    if (!moveNextSucces && !tokenSequence.movePrevious()) {
        assert false;
        return caretOffset;
    }
    boolean hasCurly = false;
    while (tokenSequence.movePrevious()) {
        if (!hasCurly) {
            if (tokenSequence.token().id() == PHPTokenId.PHP_CURLY_OPEN) {
                hasCurly = true;
            }
        } else {
            // possibly some whitespace before curly open?
            if (tokenSequence.token().id() != PHPTokenId.WHITESPACE) {
                tokenSequence.moveNext();
                break;
            }
        }
    }
    if (hasCurly) {
        return tokenSequence.offset();
    }
    assert false;
    return caretOffset;
}
 
Example 21
Source Project: netbeans   Source File: LatteCompletionHandler.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public Documentation documentElement(ParserResult info, ElementHandle element, Callable<Boolean> cancel) {
    Documentation result = null;
    if (element instanceof LatteElement) {
        result = Documentation.create(((LatteElement) element).getDocumentationText(), documentationUrl);
    }
    return result;
}
 
Example 22
Source Project: netbeans   Source File: CslTestBase.java    License: Apache License 2.0 5 votes vote down vote up
protected void initializeTypeNodes(ParserResult info, List<Object> nodes,
        Map<Object,OffsetRange> positions, Map<Object,String> types) throws Exception {
    // Override in your test
    // Associate type descriptions with a bunch of nodes.
    // For every node that has an associated type, add position and description information about it.
    // This will then be used to generate type hints in the source
}
 
Example 23
Source Project: netbeans   Source File: JsCodeCompletion.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public String document(ParserResult info, ElementHandle element) {
    Documentation doc = documentElement(info, element, new Callable<Boolean>() {
        @Override
        public Boolean call() throws Exception {
            return false;
        }
    });
    if (doc != null) {
        return doc.getContent();
    }
    return null;
}
 
Example 24
Source Project: netbeans   Source File: GroovyInstantRenamer.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public Set<OffsetRange> getRenameRegions(ParserResult info, int caretOffset) {
    LOG.log(Level.FINEST, "getRenameRegions()"); //NOI18N

    GroovyParserResult gpr = ASTUtils.getParseResult(info);
    BaseDocument doc = LexUtilities.getDocument(gpr, false);
    if (doc == null) {
        return Collections.emptySet();
    }

    AstPath path = getPathUnderCaret(gpr, caretOffset);
    return markOccurences(path, doc, caretOffset);
}
 
Example 25
@Override
public void run(ParserResult result, SchedulerEvent event) {
    SpiSupportAccessor.getInstance().setCancelSupport(cancel);
    try {
        final ElementScanningTask t = getTask();
        if (t != null) {
            t.run(result, event);
        }
    } finally {
        SpiSupportAccessor.getInstance().removeCancelSupport(cancel);
    }
}
 
Example 26
Source Project: netbeans   Source File: SanitizeSourceTest.java    License: Apache License 2.0 5 votes vote down vote up
protected String getTestResult(String filename, String caretLine) throws Exception {
    FileObject testFile = getTestFile("testfiles/" + filename + ".php");

    Source testSource = getTestSource(testFile);
    final int caretOffset;
    if (caretLine != null) {
        caretOffset = getCaretOffset(testSource.createSnapshot().getText().toString(), caretLine);
        enforceCaretOffset(testSource, caretOffset);
    } else {
        caretOffset = -1;
    }

    final StringBuffer textresult = new StringBuffer();
    ParserManager.parse(Collections.singleton(testSource), new UserTask() {
        public @Override void run(ResultIterator resultIterator) throws Exception {
            Parser.Result r = caretOffset == -1 ? resultIterator.getParserResult() : resultIterator.getParserResult(caretOffset);
            if (r != null) {
                assertTrue(r instanceof ParserResult);
                PHPParseResult phpResult = (PHPParseResult)r;
                Program program = phpResult.getProgram();

                if (program != null) {
                    textresult.append((new PrintASTVisitor()).printTree(program, 0));
                } else {
                    textresult.append("Program is null");
                }
            }
        }
    });

    return textresult.toString();
}
 
Example 27
Source Project: netbeans   Source File: OverridingMethodsImpl.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public Collection<? extends AlternativeLocation> overrides(ParserResult info, ElementHandle handle) {
    assert handle instanceof ModelElement;
    if (handle instanceof MethodScope) {
        MethodScope method = (MethodScope) handle;
        final ElementFilter methodNameFilter = ElementFilter.forName(NameKind.exact(method.getName()));
        final Set<MethodElement> overridenMethods = methodNameFilter.filter(getInheritedMethods(info, method));
        List<AlternativeLocation> retval = new ArrayList<>();
        for (MethodElement methodElement : overridenMethods) {
            retval.add(MethodLocation.newInstance(methodElement));
        }
        return retval;
    }
    return null;
}
 
Example 28
Source Project: netbeans   Source File: YamlScanner.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public List<? extends StructureItem> scan(ParserResult info) {
    YamlParserResult result = (YamlParserResult) info;
    if (result != null) {
        return result.getItems();
    }

    return Collections.emptyList();
}
 
Example 29
Source Project: netbeans   Source File: SemiAttribute.java    License: Apache License 2.0 5 votes vote down vote up
public static SemiAttribute semiAttribute(ParserResult info, int stopOffset) {
    SemiAttribute a = new SemiAttribute(info, stopOffset);

    try {
        a.scan(Utils.getRoot(info));
    } catch (Stop s) {
    }

    return a;
}
 
Example 30
Source Project: netbeans   Source File: GsfHintsProvider.java    License: Apache License 2.0 4 votes vote down vote up
List<ErrorDescription> computeErrors(Document doc, ParserResult result, List<? extends Error> errors, List<ErrorDescription> descs) {
    if (LOG.isLoggable(Level.FINE)) {
        LOG.log(Level.FINE, "errors = " + errors);
    }
    
    for (Error d : errors) {
        if (cancel.isCancelled()) {
            return null;
        }
        
        if (LOG.isLoggable(Level.FINE)) {
            LOG.log(Level.FINE, "d = " + d);

            //Map<String, List<ErrorRule>> code2Rules = RulesManager.getInstance().getErrors();
        }
        
        //Map<String, List<ErrorRule>> code2Rules = RulesManager.getInstance().getErrors();
        
        //List<ErrorRule> rules = code2Rules.get(d.getKey());
        
        //if (LOG.isLoggable(Level.FINE)) {
            //LOG.log(Level.FINE, "code= " + d.getKey());
            //LOG.log(Level.FINE, "rules = " + rules);
        //}
        
        //int position = (int)d.getPosition();
        int astOffset = d.getStartPosition();
        int astEndOffset = d.getEndPosition();
        
        int position, endPosition;
        position = result.getSnapshot().getOriginalOffset(astOffset);
        if (position == -1) {
            continue;
        }
        endPosition = position+(astEndOffset-astOffset);
        
        LazyFixList ehm;
        
        //if (rules != null) {
        //    ehm = new CreatorBasedLazyFixList(info.getFileObject(), d.getKey(), (int)getPrefferedPosition(info, d), rules, data);
        //} else {
            ehm = ErrorDescriptionFactory.lazyListForFixes(Collections.<Fix>emptyList());
        //}
        
        if (LOG.isLoggable(Level.FINE)) {
            LOG.log(Level.FINE, "ehm=" + ehm);
        }
        
        final String desc = d.getDisplayName();
        final Position[] range = getLine(d, doc, position, endPosition);
        
        if (cancel.isCancelled()) {
            return null;
        }
        
        if (range[0] == null || range[1] == null) {
            continue;
        }
        
        descs.add(ErrorDescriptionFactory.createErrorDescription(errorKind2Severity.get(d.getSeverity()), desc, ehm, doc, range[0], range[1]));
    }
    
    if (cancel.isCancelled()) {
        return null;
    }
    
    return descs;
}