001/*-------------------------------------------------------------------------+
002|                                                                          |
003| Copyright (c) 2009-2017 CQSE GmbH                                        |
004|                                                                          |
005+-------------------------------------------------------------------------*/
006package eu.cqse.check.framework.shallowparser.util;
007
008import java.util.List;
009import java.util.stream.Collectors;
010
011import org.conqat.lib.commons.string.StringUtils;
012
013import eu.cqse.check.framework.scanner.ELanguage;
014import eu.cqse.check.framework.shallowparser.IShallowParser;
015import eu.cqse.check.framework.shallowparser.ShallowParserException;
016import eu.cqse.check.framework.shallowparser.ShallowParserFactory;
017import eu.cqse.check.framework.shallowparser.TokenStreamTextUtils;
018import eu.cqse.check.framework.shallowparser.framework.ShallowEntity;
019
020/** Utilities for test cases that use shallow parsers. */
021public class ShallowParsingTestUtils {
022
023        /**
024         * Returns all shallow entities of the parsed input using
025         * {@link IShallowParser#parseTopLevel(List)}.
026         */
027        public static List<ShallowEntity> parseAllTopLevel(String input, ELanguage language) throws ShallowParserException {
028                return ShallowParserFactory.createParser(language).parseTopLevel(TokenTestUtils.tokenize(input, language));
029        }
030
031        /**
032         * Returns the first shallow entity of the parsed input using
033         * {@link IShallowParser#parseTopLevel(List)}.
034         */
035        public static ShallowEntity parseTopLevel(String input, ELanguage language) throws ShallowParserException {
036                return parseAllTopLevel(input, language).get(0);
037        }
038
039        /**
040         * * Returns the shallow entities of the parsed input using *
041         * {@link IShallowParser#parseFragment(List)}.
042         */
043        public static List<ShallowEntity> parseAllFragments(String input, ELanguage language)
044                        throws ShallowParserException {
045                return ShallowParserFactory.createParser(language).parseFragment(TokenTestUtils.tokenize(input, language));
046        }
047
048        /**
049         * Returns the first shallow entity of the parsed input using
050         * {@link IShallowParser#parseFragment(List)}.
051         */
052        public static ShallowEntity parseFragment(String input, ELanguage language) throws ShallowParserException {
053                return parseFragmentAtIndex(input, language, 0);
054        }
055
056        /**
057         * Returns the shallow entities of the parsed input using
058         * {@link IShallowParser#parseFragment(List)}.
059         */
060        public static ShallowEntity parseFragmentAtIndex(String input, ELanguage language, int index)
061                        throws ShallowParserException {
062                return parseAllFragments(input, language).get(index);
063        }
064
065        /** Parses the code either as fragment or top-level. */
066        public static List<ShallowEntity> parseEntities(String code, boolean isFragment, ELanguage language)
067                        throws ShallowParserException {
068                if (isFragment) {
069                        return ShallowParsingTestUtils.parseAllFragments(code, language);
070                }
071                return ShallowParsingTestUtils.parseAllTopLevel(code, language);
072        }
073
074        /** Normalizes the parsed result. */
075        public static String normalizeParseResult(List<ShallowEntity> entities) {
076                return StringUtils.normalizeLineSeparatorsPlatformIndependent(
077                                entities.stream().map(ShallowEntity::toString).collect(Collectors.joining()));
078        }
079
080        /**
081         * Prints the token texts of the given shallow entities. Texts of child entities
082         * are indented. Useful for debugging ShallowParsers.
083         */
084        public static String printIncludedTokensHierarchy(List<ShallowEntity> entities) {
085                StringBuilder sb = new StringBuilder();
086                insertShallowEntityText(entities, sb, 0);
087                return sb.toString();
088        }
089
090        /**
091         * Recursively inserts the token texts of the given shallow entities into the
092         * given StringBuilder. Texts of child entities are indented. Useful for
093         * debugging ShallowParsers.
094         */
095        private static void insertShallowEntityText(List<ShallowEntity> entities, StringBuilder sb, int level) {
096                for (ShallowEntity entity : entities) {
097                        for (int i = 0; i < level; i++) {
098                                sb.append("\t");
099                        }
100                        sb.append(TokenStreamTextUtils.concatTokenTexts(entity.ownStartTokens()));
101                        sb.append("\n");
102                        insertShallowEntityText(entity.getChildren(), sb, level + 1);
103                        if (!entity.ownEndTokens().isEmpty()) {
104                                for (int i = 0; i < level; i++) {
105                                        sb.append("\t");
106                                }
107                                sb.append(TokenStreamTextUtils.concatTokenTexts(entity.ownEndTokens()));
108                                sb.append("\n");
109                        }
110                }
111        }
112}