Example usage for org.eclipse.jdt.core IJavaElement FIELD

List of usage examples for org.eclipse.jdt.core IJavaElement FIELD

Introduction

In this page you can find the example usage for org.eclipse.jdt.core IJavaElement FIELD.

Prototype

int FIELD

To view the source code for org.eclipse.jdt.core IJavaElement FIELD.

Click Source Link

Document

Constant representing a field.

Usage

From source file:com.codenvy.ide.ext.java.server.internal.core.util.ASTNodeFinder.java

License:Open Source License

public TypeDeclaration findType(IType typeHandle) {
    IJavaElement parent = typeHandle.getParent();
    final char[] typeName = typeHandle.getElementName().toCharArray();
    final int occurenceCount = ((SourceType) typeHandle).occurrenceCount;
    final boolean findAnonymous = typeName.length == 0;
    class Visitor extends ASTVisitor {
        TypeDeclaration result;/*from   ww  w.ja va2  s  . c  o  m*/
        int count = 0;

        public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
            if (this.result != null)
                return false;
            if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
                if (findAnonymous && ++this.count == occurenceCount) {
                    this.result = typeDeclaration;
                }
            } else {
                if (!findAnonymous && CharOperation.equals(typeName, typeDeclaration.name)) {
                    this.result = typeDeclaration;
                }
            }
            return false; // visit only one level
        }
    }
    switch (parent.getElementType()) {
    case IJavaElement.COMPILATION_UNIT:
        TypeDeclaration[] types = this.unit.types;
        if (types != null) {
            for (int i = 0, length = types.length; i < length; i++) {
                TypeDeclaration type = types[i];
                if (CharOperation.equals(typeName, type.name)) {
                    return type;
                }
            }
        }
        break;
    case IJavaElement.TYPE:
        TypeDeclaration parentDecl = findType((IType) parent);
        if (parentDecl == null)
            return null;
        types = parentDecl.memberTypes;
        if (types != null) {
            for (int i = 0, length = types.length; i < length; i++) {
                TypeDeclaration type = types[i];
                if (CharOperation.equals(typeName, type.name)) {
                    return type;
                }
            }
        }
        break;
    case IJavaElement.FIELD:
        FieldDeclaration fieldDecl = findField((IField) parent);
        if (fieldDecl == null)
            return null;
        Visitor visitor = new Visitor();
        fieldDecl.traverse(visitor, null);
        return visitor.result;
    case IJavaElement.INITIALIZER:
        Initializer initializer = findInitializer((IInitializer) parent);
        if (initializer == null)
            return null;
        visitor = new Visitor();
        initializer.traverse(visitor, null);
        return visitor.result;
    case IJavaElement.METHOD:
        AbstractMethodDeclaration methodDecl = findMethod((IMethod) parent);
        if (methodDecl == null)
            return null;
        visitor = new Visitor();
        methodDecl.traverse(visitor, (ClassScope) null);
        return visitor.result;
    }
    return null;
}

From source file:com.codenvy.ide.ext.java.server.internal.core.util.HandleFactory.java

License:Open Source License

/**
 * Create handle by adding child to parent obtained by recursing into parent scopes.
 *///  ww  w  . j a  v a  2s .c om
private IJavaElement createElement(Scope scope, int elementPosition, ICompilationUnit unit,
        HashSet existingElements, HashMap knownScopes) {
    IJavaElement newElement = (IJavaElement) knownScopes.get(scope);
    if (newElement != null)
        return newElement;

    switch (scope.kind) {
    case Scope.COMPILATION_UNIT_SCOPE:
        newElement = unit;
        break;
    case Scope.CLASS_SCOPE:
        IJavaElement parentElement = createElement(scope.parent, elementPosition, unit, existingElements,
                knownScopes);
        switch (parentElement.getElementType()) {
        case IJavaElement.COMPILATION_UNIT:
            newElement = ((ICompilationUnit) parentElement)
                    .getType(new String(scope.enclosingSourceType().sourceName));
            break;
        case IJavaElement.TYPE:
            newElement = ((IType) parentElement).getType(new String(scope.enclosingSourceType().sourceName));
            break;
        case IJavaElement.FIELD:
        case IJavaElement.INITIALIZER:
        case IJavaElement.METHOD:
            IMember member = (IMember) parentElement;
            if (member.isBinary()) {
                return null;
            } else {
                newElement = member.getType(new String(scope.enclosingSourceType().sourceName), 1);
                // increment occurrence count if collision is detected
                if (newElement != null) {
                    while (!existingElements.add(newElement))
                        ((SourceRefElement) newElement).occurrenceCount++;
                }
            }
            break;
        }
        if (newElement != null) {
            knownScopes.put(scope, newElement);
        }
        break;
    case Scope.METHOD_SCOPE:
        IType parentType = (IType) createElement(scope.parent, elementPosition, unit, existingElements,
                knownScopes);
        MethodScope methodScope = (MethodScope) scope;
        if (methodScope.isInsideInitializer()) {
            // inside field or initializer, must find proper one
            TypeDeclaration type = methodScope.referenceType();
            int occurenceCount = 1;
            int length = type.fields == null ? 0 : type.fields.length;
            for (int i = 0; i < length; i++) {
                FieldDeclaration field = type.fields[i];
                if (field.declarationSourceStart <= elementPosition
                        && elementPosition <= field.declarationSourceEnd) {
                    switch (field.getKind()) {
                    case AbstractVariableDeclaration.FIELD:
                    case AbstractVariableDeclaration.ENUM_CONSTANT:
                        newElement = parentType.getField(new String(field.name));
                        break;
                    case AbstractVariableDeclaration.INITIALIZER:
                        newElement = parentType.getInitializer(occurenceCount);
                        break;
                    }
                    break;
                } else if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) {
                    occurenceCount++;
                }
            }
        } else {
            // method element
            AbstractMethodDeclaration method = methodScope.referenceMethod();
            newElement = parentType.getMethod(new String(method.selector),
                    Util.typeParameterSignatures(method));
            if (newElement != null) {
                knownScopes.put(scope, newElement);
            }
        }
        break;
    case Scope.BLOCK_SCOPE:
        // standard block, no element per se
        newElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes);
        break;
    }
    return newElement;
}

From source file:com.codenvy.ide.ext.java.server.javadoc.JavaElementLabelComposer.java

License:Open Source License

/**
 * Appends the label for a type. Considers the T_* flags.
 *
 * @param type the element to render/*from www.j a  v a  2s  . c o  m*/
 * @param flags the rendering flags. Flags with names starting with 'T_' are considered.
 */
public void appendTypeLabel(IType type, long flags) {

    if (getFlag(flags, JavaElementLabels.T_FULLY_QUALIFIED)) {
        IPackageFragment pack = type.getPackageFragment();
        if (!pack.isDefaultPackage()) {
            appendPackageFragmentLabel(pack, (flags & QUALIFIER_FLAGS));
            fBuffer.append('.');
        }
    }
    IJavaElement parent = type.getParent();
    if (getFlag(flags, JavaElementLabels.T_FULLY_QUALIFIED | JavaElementLabels.T_CONTAINER_QUALIFIED)) {
        IType declaringType = type.getDeclaringType();
        if (declaringType != null) {
            appendTypeLabel(declaringType, JavaElementLabels.T_CONTAINER_QUALIFIED | (flags & QUALIFIER_FLAGS));
            fBuffer.append('.');
        }
        int parentType = parent.getElementType();
        if (parentType == IJavaElement.METHOD || parentType == IJavaElement.FIELD
                || parentType == IJavaElement.INITIALIZER) { // anonymous or local
            appendElementLabel(parent, 0);
            fBuffer.append('.');
        }
    }

    String typeName;
    boolean isAnonymous = false;
    if (type.isLambda()) {
        typeName = "() -> {...}"; //$NON-NLS-1$
        try {
            String[] superInterfaceSignatures = type.getSuperInterfaceTypeSignatures();
            if (superInterfaceSignatures.length > 0) {
                typeName = typeName + ' ' + getSimpleTypeName(type, superInterfaceSignatures[0]);
            }
        } catch (JavaModelException e) {
            //ignore
        }

    } else {
        typeName = getElementName(type);
        try {
            isAnonymous = type.isAnonymous();
        } catch (JavaModelException e1) {
            // should not happen, but let's play safe:
            isAnonymous = typeName.length() == 0;
        }
        if (isAnonymous) {
            try {
                if (parent instanceof IField && type.isEnum()) {
                    typeName = '{' + JavaElementLabels.ELLIPSIS_STRING + '}';
                } else {
                    String supertypeName;
                    String[] superInterfaceSignatures = type.getSuperInterfaceTypeSignatures();
                    if (superInterfaceSignatures.length > 0) {
                        supertypeName = getSimpleTypeName(type, superInterfaceSignatures[0]);
                    } else {
                        supertypeName = getSimpleTypeName(type, type.getSuperclassTypeSignature());
                    }
                    typeName = MessageFormat.format("new {0}() '{'...}", supertypeName);
                }
            } catch (JavaModelException e) {
                //ignore
                typeName = "new Anonymous";
            }
        }
    }
    fBuffer.append(typeName);

    if (getFlag(flags, JavaElementLabels.T_TYPE_PARAMETERS)) {
        if (getFlag(flags, JavaElementLabels.USE_RESOLVED) && type.isResolved()) {
            BindingKey key = new BindingKey(type.getKey());
            if (key.isParameterizedType()) {
                String[] typeArguments = key.getTypeArguments();
                appendTypeArgumentSignaturesLabel(type, typeArguments, flags);
            } else {
                String[] typeParameters = Signature.getTypeParameters(key.toSignature());
                appendTypeParameterSignaturesLabel(typeParameters, flags);
            }
        } else if (type.exists()) {
            try {
                appendTypeParametersLabels(type.getTypeParameters(), flags);
            } catch (JavaModelException e) {
                // ignore
            }
        }
    }

    // category
    if (getFlag(flags, JavaElementLabels.T_CATEGORY) && type.exists()) {
        try {
            appendCategoryLabel(type, flags);
        } catch (JavaModelException e) {
            // ignore
        }
    }

    // post qualification
    if (getFlag(flags, JavaElementLabels.T_POST_QUALIFIED)) {
        int offset = fBuffer.length();
        fBuffer.append(JavaElementLabels.CONCAT_STRING);
        IType declaringType = type.getDeclaringType();
        if (declaringType == null && type.isBinary() && isAnonymous) {
            // workaround for Bug 87165: [model] IType#getDeclaringType() does not work for anonymous binary type
            String tqn = type.getTypeQualifiedName();
            int lastDollar = tqn.lastIndexOf('$');
            if (lastDollar != 1) {
                String declaringTypeCF = tqn.substring(0, lastDollar) + ".class"; //$NON-NLS-1$
                declaringType = type.getPackageFragment().getClassFile(declaringTypeCF).getType();
                try {
                    ISourceRange typeSourceRange = type.getSourceRange();
                    if (declaringType.exists() && SourceRange.isAvailable(typeSourceRange)) {
                        IJavaElement realParent = declaringType.getTypeRoot()
                                .getElementAt(typeSourceRange.getOffset() - 1);
                        if (realParent != null) {
                            parent = realParent;
                        }
                    }
                } catch (JavaModelException e) {
                    // ignore
                }
            }
        }
        if (declaringType != null) {
            appendTypeLabel(declaringType, JavaElementLabels.T_FULLY_QUALIFIED | (flags & QUALIFIER_FLAGS));
            int parentType = parent.getElementType();
            if (parentType == IJavaElement.METHOD || parentType == IJavaElement.FIELD
                    || parentType == IJavaElement.INITIALIZER) { // anonymous or local
                fBuffer.append('.');
                appendElementLabel(parent, 0);
            }
        } else {
            appendPackageFragmentLabel(type.getPackageFragment(), flags & QUALIFIER_FLAGS);
        }
        //         if (getFlag(flags, JavaElementLabels.COLORIZE)) {
        //            fBuffer.setStyle(offset, fBuffer.length() - offset, QUALIFIER_STYLE);
        //         }
    }
}

From source file:com.codenvy.ide.ext.java.server.JavadocFinder.java

License:Open Source License

private String getInfoText(IJavaElement element, ITypeRoot editorInputElement, boolean allowImage) {
    long flags = getHeaderFlags(element);
    StringBuffer label = new StringBuffer(JavaElementLinks.getElementLabel(element, flags));

    if (element.getElementType() == IJavaElement.FIELD) {
        String constantValue = getConstantValue((IField) element, editorInputElement);
        if (constantValue != null) {
            constantValue = HTMLPrinter.convertToHTMLContentWithWhitespace(constantValue);
            IJavaProject javaProject = element.getJavaProject();
            label.append(getFormattedAssignmentOperator(javaProject));
            label.append(constantValue);
        }/*  w w w. ja v a  2  s  .  c o m*/
    }

    //      if (element.getElementType() == IJavaElement.METHOD) {
    //         IMethod method= (IMethod)element;
    //         //TODO: add default value for annotation type members, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=249016
    //      }

    return getImageAndLabel(element, allowImage, label.toString());
}

From source file:com.drgarbage.asm.render.impl.OutlineElementField.java

License:Apache License

/**
 * Constructs a method outline object./*from w ww .  j  av a  2  s  .  co m*/
 * @param parent
 */
public OutlineElementField(IType parent, IClassFileDocument document, int fieldIndex) {
    super(com.drgarbage.asm.Opcodes.ASM4);
    this.classFileDocument = document;
    this.fieldIndex = fieldIndex;
    setElementType(IJavaElement.FIELD);
    setDeclaringType(parent);
}

From source file:com.drgarbage.bytecodevisualizer.editors.BytecodeEditor.java

License:Apache License

/**
 * Selects the given line and revaluate visible position.
 * @param bytecodeDocumentLine the line number of the bytecode document
 * @param elementName // w  w  w  .  ja  v  a  2  s.co  m
 * @param elementType the element type one of {@link IJavaElement IJavaElement.CLASS_FILE},
 *       {@link IJavaElement IJavaElement.FIELD} or {@link IJavaElement IJavaElement.METHOD}.
 * @see IJavaElement
 */
public void selectBytecodeLineAndReveal(int bytecodeDocumentLine, String elementName, int elementType) {
    IDocument document = byteCodeDocumentProvider.getBytecodeDocument(getBytecodeEditorInput());
    try {
        /* get line information */
        IRegion region = document.getLineInformation(bytecodeDocumentLine);
        int lineStartOffset = region.getOffset();
        int lineLenght = region.getLength();
        String lineString = document.get(lineStartOffset, lineLenght);

        if (elementName == null) {
            super.selectAndReveal(lineStartOffset, 0);
        }

        int elementIndex, elementLength;
        switch (elementType) {
        case IJavaElement.CLASS_FILE:
            elementIndex = lineString.indexOf(" " + elementName + " {") + 1;
            break;
        case IJavaElement.FIELD:
            elementIndex = lineString.indexOf(" " + elementName + ";") + 1;
            break;
        case IJavaElement.METHOD:
            elementIndex = lineString.indexOf(" " + elementName + "(") + 1;
            break;
        default:
            elementIndex = 0;
            elementLength = 0;
        }

        /* name not found */
        if (elementIndex == 0) {
            elementLength = 0;
        } else {
            elementLength = elementName.length();
        }

        super.selectAndReveal(lineStartOffset + elementIndex, elementLength);

    } catch (BadLocationException e) {
        /*nothing to do */}
}

From source file:com.drgarbage.bytecodevisualizer.editors.BytecodeEditor.java

License:Apache License

/**
 * Selects the line for the given element:
 * - ClassFileSection//www . j  a va 2s. c  o  m
 * - MethodSection
 * - Variable
 * 
 * @param element
 * @param line
 * @param markLine true if the line has to be marked
 */
public void setSelection(IJavaElement element, int line, boolean markLine) {

    if (element == null) {
        return;
    }

    switch (element.getElementType()) {
    case IJavaElement.FIELD: /* select field */
        String fieldName = element.getElementName();
        IFieldSection fieldSection = byteCodeDocumentProvider.getClassFileDocument()
                .findFieldSection(fieldName);
        if (fieldSection != null) {
            selectBytecodeLineAndReveal(fieldSection.getBytecodeDocumentLine(), fieldName, IJavaElement.FIELD);
        }
        break;
    case IJavaElement.METHOD: /* select method */
        IMethod method = (IMethod) element;
        try {
            String methodName;
            if (method.isConstructor()) {
                methodName = "<init>";
            } else {
                methodName = method.getElementName();
            }

            String methodSignature = ClassFileDocumentsUtils.resolveMethodSignature(method);
            IMethodSection methodSection = byteCodeDocumentProvider.getClassFileDocument()
                    .findMethodSection(methodName, methodSignature);

            if (methodSection != null) {
                if (line == IClassFileEditor.INVALID_LINE || line == IClassFileEditor.METHOD_DECLARATION_LINE) {

                    if (method.isConstructor()) {
                        methodName = method.getElementName();
                    }
                    selectBytecodeLineAndReveal(methodSection.getFirstLine(), methodName, IJavaElement.METHOD);
                } else {
                    selectLineAndRevaluate2(methodSection.getBytecodeLine(line) - 1, markLine);
                }
                break;
            }

        } catch (JavaModelException e) {
            BytecodeVisualizerPlugin
                    .log(new Status(IStatus.ERROR, BytecodeVisualizerPlugin.PLUGIN_ID, e.getMessage(), e));
        }

    default:
        /* select class */
        IClassFileDocument doc = byteCodeDocumentProvider.getClassFileDocument();
        if (doc != null) {
            int docLine = doc.getClassSignatureDocumentLine();
            selectBytecodeLineAndReveal(docLine, element.getElementName(), IJavaElement.CLASS_FILE);
        }
    }

    /* call cursor hook */
    doHandleCursorPositionChanged();
}

From source file:com.drgarbage.bytecodevisualizer.editors.ToggleBytecodeBreakpointAdapter.java

License:Apache License

public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {

    ISelection sel = translateToMembers(part, selection);
    if (sel instanceof IStructuredSelection) {
        IStructuredSelection structuredSelection = (IStructuredSelection) sel;
        if (!structuredSelection.isEmpty()) {
            IMember member = (IMember) structuredSelection.getFirstElement();
            int mtype = member.getElementType();
            if (mtype == IJavaElement.FIELD) {
                toggleWatchpoints(part, sel);
            } else if (mtype == IJavaElement.METHOD) {
                toggleMethodBreakpoints(part, sel);
            } else if (member.getElementType() == IJavaElement.TYPE) {
                toggleClassBreakpoints(part, sel);
            } else {
                BytecodeVisualizerPlugin
                        .log(new IllegalStateException("Uncovered element type " + member.getElementType()));
                //               /*
                //                * fall back to old behavior, always create a line
                //                * breakpoint
                //                */
                //               /* should never occur */
                //               toggleLineBreakpoints(part, selection, true);
            }/*from   ww w .jav  a2  s  .  c  o  m*/
        }

    }
}

From source file:com.github.elucash.lambda4jdt.FoldingStructureProvider.java

License:Open Source License

/**
 * Computes the folding structure for a given {@link IJavaElement java element}. Computed
 * projection annotations are//  ww  w  .j  a v  a  2  s  . c  o m
 * {@link FoldingStructureProvider.FoldingStructureComputationContext#addProjectionRange(FoldingStructureProvider.JavaProjectionAnnotation, Position)
 * added} to the computation context.
 * <p>
 * Subclasses may extend or replace. The default implementation creates projection annotations for
 * the following elements:
 * <ul>
 * <li>true members (not for top-level types)</li>
 * <li>the javadoc comments of any member</li>
 * <li>header comments (javadoc or multi-line comments appearing before the first type's javadoc
 * or before the package or import declarations).</li>
 * </ul>
 * </p>
 * @param element the java element to compute the folding structure for
 * @param ctx the computation context
 */
protected void computeFoldingStructure(IJavaElement element, FoldingStructureComputationContext ctx) {

    IMethod lambdaMethod = null;
    /*      boolean importContainer = false;*/
    boolean collapse = false;
    boolean collapseCode = true;
    switch (element.getElementType()) {

    case IJavaElement.IMPORT_CONTAINER: {

        IImportContainer importContainer = (IImportContainer) element;
        IRegion projectionRegion = computeImportProjectionRanges(importContainer, ctx);

        if (projectionRegion != null) {
            JavaImportPosition importPosition = new JavaImportPosition(projectionRegion, importContainer);

            ctx.addProjectionRange(
                    new JavaProjectionAnnotation(ctx.collapseImportContainer(), ctx, element, true),
                    importPosition);
        }

        return;
    }
    case IJavaElement.TYPE:
        collapseCode = isInnerType((IType) element) && !isAnonymousEnum((IType) element);
        collapse = ctx.collapseInnerTypes() && collapseCode;

        lambdaMethod = findLambdaMethodIn(element);

        if (lambdaMethod != null) {
            // Let collapse initially by default
            collapse = ctx.initial;
        } else {
            try {
                if (((IType) element).isAnonymous())
                    return;
            } catch (Exception e) {
            }
        }
        break;
    case IJavaElement.METHOD:
    case IJavaElement.FIELD:
    case IJavaElement.INITIALIZER:
        collapse = ctx.collapseMembers();
        collapseCode = false;
        break;
    default:
        return;
    }

    IRegion[] regions = computeProjectionRanges((ISourceReference) element, ctx);

    if (regions.length == 0)
        return;

    // comments
    for (int i = 0; i < regions.length - 1; i++) {
        IRegion normalized = alignRegion(regions[i], ctx);
        if (normalized != null) {
            Position position = createCommentPosition(normalized);
            if (position != null) {
                boolean commentCollapse;
                if (i == 0 && (regions.length > 2 || ctx.hasHeaderComment()) && element == ctx.getFirstType()) {
                    commentCollapse = ctx.collapseHeaderComments();
                } else {
                    commentCollapse = ctx.collapseJavadoc();
                }
                ctx.addProjectionRange(new JavaProjectionAnnotation(commentCollapse, ctx, element, true),
                        position);
            }
        }
    }
    // code
    if (!collapseCode)
        return;

    // IRegion lastRegion = regions[regions.length - 1];

    IRegion codeRegion = regions[regions.length - 1];

    // if (lambdaMethod != null) {
    // normalized = alignRegion(lastRegion, ctx);
    // }

    if (codeRegion != null) {
        Position position = element instanceof IMember
                ? createMemberPosition(codeRegion, (IMember) element, lambdaMethod)
                : createCommentPosition(codeRegion);

        if (position != null)
            ctx.addProjectionRange(new JavaProjectionAnnotation(collapse, ctx, element, false), position);
    }
}

From source file:com.google.gwt.eclipse.core.search.JavaQueryParticipant.java

License:Open Source License

private Set<IIndexedJavaRef> findMatches(ElementQuerySpecification query, boolean resolveMatches) {
    IJavaElement javaElement = query.getElement();
    JavaRefIndex index = JavaRefIndex.getInstance();
    int elementType = javaElement.getElementType();

    // Type matches are easy: just compare the fully-qualified type name, and if
    // they are equal, then we have a match
    if (elementType == IJavaElement.TYPE) {
        String typeName = ((IType) javaElement).getFullyQualifiedName();
        return index.findTypeReferences(typeName);
    }/*  w w w .  ja v a 2 s  .co m*/

    // Besides types, we only support searching for fields and methods
    if (elementType != IJavaElement.FIELD && elementType != IJavaElement.METHOD) {
        return Collections.emptySet();
    }

    // Get the type that actually declares this member (could be a super type)
    IType declType = ((IMember) javaElement).getDeclaringType();
    assert (declType != null && declType.exists());

    // Search the index for matches based only on the member name and type
    Set<IIndexedJavaRef> nameMatches = (elementType == IJavaElement.METHOD)
            ? index.findMethodReferences(javaElement.getElementName())
            : index.findFieldReferences(javaElement.getElementName());

    // We optionally return the full set of "potential" matches (i.e., index
    // entries that match by name but may not resolve to the query element)
    if (!resolveMatches) {
        return nameMatches;
    }

    Set<IIndexedJavaRef> matches = new HashSet<IIndexedJavaRef>();
    for (IIndexedJavaRef nameMatch : nameMatches) {
        /*
         * Try to resolve each potential match to see if it actually references
         * the target Java element. This takes care of matching the method
         * parameter lists, as well as correctly searching for a super type's
         * members from a reference to one of its subclasses.
         */
        IJavaElement matchElement = nameMatch.resolve();
        if (javaElement.equals(matchElement)) {
            matches.add(nameMatch);
        }
    }

    return matches;
}