001/*-------------------------------------------------------------------------+
002|                                                                          |
003| Copyright 2005-2011 the ConQAT Project                                   |
004|                                                                          |
005| Licensed under the Apache License, Version 2.0 (the "License");          |
006| you may not use this file except in compliance with the License.         |
007| You may obtain a copy of the License at                                  |
008|                                                                          |
009|    http://www.apache.org/licenses/LICENSE-2.0                            |
010|                                                                          |
011| Unless required by applicable law or agreed to in writing, software      |
012| distributed under the License is distributed on an "AS IS" BASIS,        |
013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
014| See the License for the specific language governing permissions and      |
015| limitations under the License.                                           |
016+-------------------------------------------------------------------------*/
017package eu.cqse.check.framework.shallowparser;
018
019import static eu.cqse.check.framework.scanner.ELanguage.ABAP;
020import static eu.cqse.check.framework.scanner.ELanguage.ADA;
021import static eu.cqse.check.framework.scanner.ELanguage.COBOL;
022import static eu.cqse.check.framework.scanner.ELanguage.CPP;
023import static eu.cqse.check.framework.scanner.ELanguage.CS;
024import static eu.cqse.check.framework.scanner.ELanguage.DELPHI;
025import static eu.cqse.check.framework.scanner.ELanguage.FORTRAN;
026import static eu.cqse.check.framework.scanner.ELanguage.GO;
027import static eu.cqse.check.framework.scanner.ELanguage.GOSU;
028import static eu.cqse.check.framework.scanner.ELanguage.GROOVY;
029import static eu.cqse.check.framework.scanner.ELanguage.IEC61131;
030import static eu.cqse.check.framework.scanner.ELanguage.JAVA;
031import static eu.cqse.check.framework.scanner.ELanguage.JAVASCRIPT;
032import static eu.cqse.check.framework.scanner.ELanguage.KOTLIN;
033import static eu.cqse.check.framework.scanner.ELanguage.LINE;
034import static eu.cqse.check.framework.scanner.ELanguage.MATLAB;
035import static eu.cqse.check.framework.scanner.ELanguage.OBJECTIVE_C;
036import static eu.cqse.check.framework.scanner.ELanguage.OCAML;
037import static eu.cqse.check.framework.scanner.ELanguage.OPEN_CL;
038import static eu.cqse.check.framework.scanner.ELanguage.OSCRIPT;
039import static eu.cqse.check.framework.scanner.ELanguage.PHP;
040import static eu.cqse.check.framework.scanner.ELanguage.PLSQL;
041import static eu.cqse.check.framework.scanner.ELanguage.PYTHON;
042import static eu.cqse.check.framework.scanner.ELanguage.RUBY;
043import static eu.cqse.check.framework.scanner.ELanguage.RUST;
044import static eu.cqse.check.framework.scanner.ELanguage.SQLSCRIPT;
045import static eu.cqse.check.framework.scanner.ELanguage.SWIFT;
046import static eu.cqse.check.framework.scanner.ELanguage.TSQL;
047import static eu.cqse.check.framework.scanner.ELanguage.VB;
048import static eu.cqse.check.framework.scanner.ELanguage.XTEND;
049
050import java.util.EnumMap;
051import java.util.EnumSet;
052import java.util.Map;
053import java.util.function.Supplier;
054
055import eu.cqse.check.framework.scanner.ELanguage;
056import eu.cqse.check.framework.shallowparser.languages.abap.AbapShallowParser;
057import eu.cqse.check.framework.shallowparser.languages.ada.AdaShallowParser;
058import eu.cqse.check.framework.shallowparser.languages.cobol.CobolShallowParser;
059import eu.cqse.check.framework.shallowparser.languages.cpp.CppShallowParser;
060import eu.cqse.check.framework.shallowparser.languages.cs.CsShallowParser;
061import eu.cqse.check.framework.shallowparser.languages.delphi.DelphiShallowParser;
062import eu.cqse.check.framework.shallowparser.languages.fortran.FortranShallowParser;
063import eu.cqse.check.framework.shallowparser.languages.go.GoShallowParser;
064import eu.cqse.check.framework.shallowparser.languages.gosu.GosuShallowParser;
065import eu.cqse.check.framework.shallowparser.languages.groovy.GroovyShallowParser;
066import eu.cqse.check.framework.shallowparser.languages.hanasqlscript.HanaSQLScriptShallowParser;
067import eu.cqse.check.framework.shallowparser.languages.iec61131.Iec61131ShallowParser;
068import eu.cqse.check.framework.shallowparser.languages.java.JavaShallowParser;
069import eu.cqse.check.framework.shallowparser.languages.javascript.JavaScriptShallowParser;
070import eu.cqse.check.framework.shallowparser.languages.kotlin.KotlinShallowParser;
071import eu.cqse.check.framework.shallowparser.languages.line.LineShallowParser;
072import eu.cqse.check.framework.shallowparser.languages.matlab.MatlabShallowParser;
073import eu.cqse.check.framework.shallowparser.languages.objectivec.ObjectiveCShallowParser;
074import eu.cqse.check.framework.shallowparser.languages.ocaml.OcamlShallowParser;
075import eu.cqse.check.framework.shallowparser.languages.opencl.OpenCLShallowParser;
076import eu.cqse.check.framework.shallowparser.languages.oscript.OScriptShallowParser;
077import eu.cqse.check.framework.shallowparser.languages.php.PhpShallowParser;
078import eu.cqse.check.framework.shallowparser.languages.plsql.PlsqlShallowParser;
079import eu.cqse.check.framework.shallowparser.languages.python.PythonShallowParser;
080import eu.cqse.check.framework.shallowparser.languages.ruby.RubyShallowParser;
081import eu.cqse.check.framework.shallowparser.languages.rust.RustShallowParser;
082import eu.cqse.check.framework.shallowparser.languages.swift.SwiftShallowParser;
083import eu.cqse.check.framework.shallowparser.languages.tsql.TsqlShallowParser;
084import eu.cqse.check.framework.shallowparser.languages.visualbasic.VisualBasicShallowParser;
085import eu.cqse.check.framework.shallowparser.languages.xtend.XtendShallowParser;
086
087/** Factory class for creation of shallow parsers and utility methods. */
088public class ShallowParserFactory {
089
090        /** The map of parsers (initialized lazily). */
091        private static Map<ELanguage, IShallowParser> parsers = new EnumMap<>(ELanguage.class);
092
093        /** The map of parsers (the parsers are created lazily). */
094        private static Map<ELanguage, Supplier<IShallowParser>> parserFactories = new EnumMap<>(ELanguage.class);
095
096        static {
097                register(JAVA, JavaShallowParser::new);
098                register(ADA, AdaShallowParser::new);
099                register(CS, CsShallowParser::new);
100                register(CPP, CppShallowParser::new);
101                register(PLSQL, PlsqlShallowParser::new);
102                register(ABAP, AbapShallowParser::new);
103                register(JAVASCRIPT, JavaScriptShallowParser::new);
104                register(RUBY, RubyShallowParser::new);
105                register(PYTHON, PythonShallowParser::new);
106                register(DELPHI, DelphiShallowParser::new);
107                register(MATLAB, MatlabShallowParser::new);
108                register(FORTRAN, FortranShallowParser::new);
109                register(IEC61131, Iec61131ShallowParser::new);
110                register(XTEND, XtendShallowParser::new);
111                register(OCAML, OcamlShallowParser::new);
112                register(TSQL, TsqlShallowParser::new);
113                register(GROOVY, GroovyShallowParser::new);
114                register(PHP, PhpShallowParser::new);
115                register(SQLSCRIPT, HanaSQLScriptShallowParser::new);
116                register(OPEN_CL, OpenCLShallowParser::new);
117                register(RUST, RustShallowParser::new);
118                register(VB, VisualBasicShallowParser::new);
119                register(SWIFT, SwiftShallowParser::new);
120                register(GOSU, GosuShallowParser::new);
121                register(OSCRIPT, OScriptShallowParser::new);
122                register(COBOL, CobolShallowParser::new);
123                register(KOTLIN, KotlinShallowParser::new);
124                register(LINE, LineShallowParser::new);
125                register(OBJECTIVE_C, ObjectiveCShallowParser::new);
126                register(GO, GoShallowParser::new);
127        }
128
129        /** Registers a shallow parser. */
130        private static void register(ELanguage language, Supplier<IShallowParser> parserFactory) {
131                parserFactories.put(language, parserFactory);
132        }
133
134        /**
135         * Returns a new parser for the given language.
136         * <p>
137         * While we call this method "create" for consistency with other factories, the
138         * parsers are actually created only once and then cached for reuse. The reason
139         * is that parser creation may be expensive, especially when many very small
140         * code fragments are to be parsed. Reusing parsers is possible as the parsers
141         * do not hold state of a specific parse and even can be used concurrently in
142         * multiple threads.
143         * 
144         * @throws ShallowParserException
145         *             if the language is not (yet) supported by our framework.
146         */
147        public static synchronized IShallowParser createParser(ELanguage language) throws ShallowParserException {
148                if (!parsers.containsKey(language)) {
149                        Supplier<IShallowParser> factory = parserFactories.get(language);
150                        if (factory == null) {
151                                throw new ShallowParserException("Shallow parsing for language " + language + " not yet supported!");
152                        }
153                        parsers.put(language, factory.get());
154                }
155                return parsers.get(language);
156        }
157
158        /**
159         * Returns whether the given language is supported by the parser factory.
160         */
161        public static boolean supportsLanguage(ELanguage language) {
162                return parserFactories.containsKey(language);
163        }
164
165        /**
166         * Returns all {@link ELanguage}s for which we have shallow parsers.
167         */
168        public static EnumSet<ELanguage> getSupportedLanguages() {
169                return EnumSet.copyOf(parserFactories.keySet());
170        }
171}