Package org.erlide.test_support.ui.trace

Source Code of org.erlide.test_support.ui.trace.HyperlinkDetector

package org.erlide.test_support.ui.trace;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.erlide.ui.util.ErlModelUtils;
import org.erlide.util.ErlLogger;

public class HyperlinkDetector extends AbstractHyperlinkDetector {

    public HyperlinkDetector() {
    }

    @Override
    public IHyperlink[] detectHyperlinks(final ITextViewer textViewer,
            final IRegion region, final boolean canShowMultipleHyperlinks) {

        if (region == null || textViewer == null) {
            return null;
        }

        final IDocument document = textViewer.getDocument();
        final int offset = region.getOffset();

        if (document == null) {
            return null;
        }

        IRegion lineInfo;
        String line;
        try {
            lineInfo = document.getLineInformationOfOffset(offset);
            line = document.get(lineInfo.getOffset(), lineInfo.getLength());
        } catch (final BadLocationException ex) {
            return null;
        }
        final int offsetInLine = offset - lineInfo.getOffset();

        IRegion r = getLink(line, offsetInLine);
        if (r != null) {
            final String text = line.substring(r.getOffset(),
                    r.getOffset() + r.getLength());
            r = new Region(lineInfo.getOffset() + r.getOffset(), r.getLength());

            return new IHyperlink[] { new TraceHyperlink(r, text) };
        }
        return null;
    }

    private IRegion getLink(final String line, final int offsetInLine) {
        final int offset = 33;

        int pos = line.indexOf(" ->", offset);
        if (pos < 0) {
            if (line.indexOf('(') < 0) {
                return null;
            }
            pos = line.length();
        }
        return new Region(offset, pos - offset);
    }

    private static class TraceHyperlink implements IHyperlink {
        private final IRegion region;
        private final String text;

        public TraceHyperlink(final IRegion region, final String text) {
            this.text = text;
            this.region = region;
        }

        @Override
        public String getTypeLabel() {
            return null;
        }

        @Override
        public String getHyperlinkText() {
            return text;
        }

        @Override
        public void open() {
            final String[] mf = text.split(":");
            final String module = mf[0];
            String function = mf[1];
            int arity;

            final int slash = function.indexOf('/');
            if (function.matches("'-[^/]+/[0-9]+-fun-.*")) {
                arity = Integer.parseInt(function.substring(slash + 1,
                        function.indexOf('-', slash)));
                function = function.substring(2, slash);
            } else {
                if (slash < 0) {
                    final int pos = function.indexOf('(');
                    arity = countArgs(function.substring(pos + 1, function.length() - 1));
                    function = function.substring(0, pos);
                } else {
                    final String args = function.substring(slash + 1);
                    arity = Integer.parseInt(args);
                    function = function.substring(0, slash);
                }
            }

            try {
                ErlModelUtils.openMFA(module, function, arity);
            } catch (final CoreException e) {
                ErlLogger.warn("Could not open %s:%s/%d", module, function, arity);
            }
        }

        private int countArgs(final String args) {
            if (args.length() == 0) {
                return 0;
            }
            return countArgs(args, 0, 1, 0);
        }

        private int countArgs(final String args, final int i0, final int n, final int p) {
            int i = i0;
            if (args.length() == i) {
                return n;
            }
            final char c = args.charAt(i++);
            if (c == '[') {
                return countArgs(args, i, n, p + 1);
            } else if (c == '{') {
                return countArgs(args, i, n, p + 1);
            } else if (c == '}') {
                return countArgs(args, i, n, p - 1);
            } else if (c == ']') {
                return countArgs(args, i, n, p - 1);
            } else if (c == ',') {
                if (p == 0) {
                    return countArgs(args, i, n + 1, p);
                }
                return countArgs(args, i, n, p);
            } else {
                return countArgs(args, i, n, p);
            }
        }

        @Override
        public IRegion getHyperlinkRegion() {
            return region;
        }
    }
}
TOP

Related Classes of org.erlide.test_support.ui.trace.HyperlinkDetector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.