eu.cqse.check.framework.scanner.ELanguage Maven / Gradle / Ivy
Show all versions of teamscale-commons Show documentation
/*-------------------------------------------------------------------------+
| |
| Copyright 2005-2011 The ConQAT Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+-------------------------------------------------------------------------*/
package eu.cqse.check.framework.scanner;
import java.io.File;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.conqat.lib.commons.collections.CollectionUtils;
import org.conqat.lib.commons.collections.ListMap;
import org.conqat.lib.commons.filesystem.FileSystemUtils;
import org.conqat.lib.commons.js_export.ExportToTypeScript;
import org.conqat.lib.commons.resources.Resource;
/**
* Enumeration class for the languages support by the scanner framework.
*
* This class is used for communication with IDE clients (via the
* {@link org.conqat.engine.service.shared.client.IdeServiceClient}), so special
* care has to be taken when changing its signature!
*/
@ExportToTypeScript
public enum ELanguage {
// we need to use the ugly workaround with asHashSet here as we cannot use
// varargs twice in the constructor
/** Java */
JAVA("Java", true, "java"),
/** C/C++ */
CPP("C/C++", true, "cpp", "cc", "c", "h", "hh", "hpp", "cxx", "hxx", "inl", "inc", "pc"),
/** OpenCL C/C++ */
OPEN_CL("OpenCL C/C++", true, "cl"),
/** Rust */
RUST("Rust", true, "rs"),
/** Visual Basic */
VB("Visual Basic", false, "vb", "frm", "cls", "bas"),
/** PL/I */
PL1("PL/I", false, "pl1", "pli"),
/** COBOL */
COBOL("COBOL", false, "cbl", "cob", "cobol", "cpy", "eco"),
/** C# */
CS("C#", true, "cs"),
/** ABAP */
ABAP("ABAP", false, "abap"),
/**
* ABAP Dictionary. This is a textual representation of objects in the ABAP
* Dictionary (aka DDIC). The format is based on the textual format for
* structure and database table definition which is available starting with SAP
* ABP Platform v7.51 or v7.52 respectively. See
* https://help.sap.com/doc/abapdocu_752_index_htm/7.52/de-DE/abenddic_tools.htm.
* This format is again based on the SAP CDS DDL
* https://help.sap.com/doc/abapdocu_752_index_htm/7.52/de-DE/abencds_f1_ddl_syntax.htm.
* If available, we export ABAP DDIC objects in the textual representation as
* provided by the SAP system, otherwise our Teamscale Connector for the SAP
* ABAP Platform serializes the text in a similar format.
*/
ABAP_DDIC("ABAP Dictionary", false, "abap_ddic"),
/** Ada */
ADA("Ada", false, "ada", "ads", "adb"),
/** Natural language text */
TEXT("Plain Text", false, "txt"),
/** XML */
XML("XML", true, "xml", "xsl", "xslt", "architecture", "cqb", "csproj", "config"),
/** HANA SQLScript */
SQLSCRIPT("HANA SQLScript", false, "sql", "hdbprocedure", "hdbfunction", "hdbscalarfunction", "hdbtablefunction"),
/**
* HANA Views XML. This includes view specifications which of SAP HANA database
* which are stored in XML. Does NOT include HANA code which is not XML (e.g.
* *.hdbview)
*/
HANA_VIEW("HANA View", true, "analyticview", "attributeview", "calculationview"),
/** PL/SQL */
PLSQL("PL/SQL", false, "sql", "pks", "pkb", "trg", "fnc", "typ", "tyb", "prc", "plsql"),
/** Python */
PYTHON("Python", true, "py"),
/** T-SQL aka Transact SQL. */
TSQL("Transact-SQL", false, "tsql"),
/** Matlab */
MATLAB("Matlab", true, "m"),
/** PHP */
PHP("PHP", true, "php", "php3", "php4", "php5"),
/** Ruby */
RUBY("Ruby", true, "rb"),
/**
* JavaScript including EcmaScript and TypeScript.
*
* Note that the statement oracle only works if semicolons are used
* consistently. However, semicolons are optional in JavaScript (rules described
* here: http://bclary.com/2004/11/07/#a-7.9), but to determine end of statement
* in this case requires a full blown parser (hard to decide locally in some
* cases). As most coding guidelines recommend using semicolons anyway, we stick
* with this solution.
*/
JAVASCRIPT("JavaScript/TypeScript", true, "js", "sj", "ts", "tsx"),
/** The language used within the M/Text printing system. */
MTEXT("M/TEXT", true, "mtx"),
/**
* The "Just Your Average Computer Company Procedural Language". A C-like
* language being part of the Panther framework developed by the company
* Prolifics. The language is used in the archive system d.3 developed by the
* company "d.velop".
*/
JPL("JPL", true, "jpl"),
/**
* Use this for languages for which no dedicated scanner is available. Creates a
* token per line (and creates EOL tokens).
*/
LINE("Line-based Text", false),
/** Delphi */
DELPHI("Delphi", false, "pas", "dpr"),
/**
* IEC 61131-3 Structured Text. We understand both the code (PU) and variable
* structure (SV).
*
* - .pou files contain program code (written in ST language)
* - .dt files contain type declarations (written in ST language)
*
* Sadly, the file endings and format are not standardized in IEC-61131-3.
*/
IEC61131("IEC 61131-3 ST", true, "pu", "sv", "st", "scl", "pou", "dt", "var"),
/** Fortran */
FORTRAN("Fortran", false, "f", "for", "f77", "f90", "f95", "f03"),
/** Xtend */
XTEND("Xtend", true, "xtend"),
/** Swift */
SWIFT("Swift", true, "swift"),
/** OCaml */
OCAML("OCaml", true, "ml", "mli"),
/** Opentext Oscript */
OSCRIPT("OScript", true, "osx", "lxe", "os"),
/** Groovy */
GROOVY("Groovy", true, "groovy"),
/** Requirement documents. */
NL_REQUIREMENTS("Natural Language Requirements", false),
/** Requirement documents. */
NL_TESTS("Natural Language Tests", false),
/** Simulink and Stateflow. */
SIMULINK("Simulink and Stateflow", false, "mdl", "slx", "sldd"),
/** Gosu (https://gosu-lang.github.io/). */
GOSU("Gosu", true, "gsp", "gs", "gsx", "gr", "grs"),
/** Kotlin. */
KOTLIN("Kotlin", true, "kt", "kts", "ktm"),
/** Objective C. */
OBJECTIVE_C("Objective-C", true, "m", "h"),
/** JavaDoc */
JAVADOC("JavaDoc", true),
/** Go */
GO("Go", true, "go");
/** List of languages that do not have methods. */
private static final EnumSet LANGUAGES_WITHOUT_METHODS = EnumSet.of(ABAP_DDIC, LINE, NL_REQUIREMENTS,
NL_TESTS, TEXT, XML, HANA_VIEW);
/** This maps from extensions to languages. */
private static final ListMap EXTENSION_2_LANGUAGE_MAP = new ListMap<>();
/** Initialize {@link #EXTENSION_2_LANGUAGE_MAP}. */
static {
for (ELanguage language : values()) {
for (String extension : language.extensions) {
EXTENSION_2_LANGUAGE_MAP.add(extension.toLowerCase(), language);
}
}
}
/** The readable name of the language, to be used, e.g., in a UI. */
private final String readableName;
/** Whether the language is case sensitive. */
private final boolean caseSensitive;
/** File extensions commonly used for this language. */
private final String[] extensions;
/** Create language. */
ELanguage(String readableName, boolean caseSensitive, String... extensions) {
this.readableName = readableName;
this.caseSensitive = caseSensitive;
this.extensions = extensions;
}
/** Returns {@link #readableName}. */
public String getReadableName() {
return readableName;
}
/** Return whether the language is case sensitive. */
public boolean isCaseSensitive() {
return caseSensitive;
}
/** Get the file extensions commonly used for this language. */
public String[] getFileExtensions() {
return CollectionUtils.copyArray(extensions);
}
/**
* Gets the {@link ELanguage} value corresponding to the extension of the
* resource. Returns null if no extension was found. If there are multiple
* possible languages, the first one is returned.
*/
public static ELanguage fromResource(Resource resource) {
return fromFileExtension(resource.getExtension());
}
/**
* Gets the {@link ELanguage} value corresponding to the file extension of the
* path. Returns null if no extension was found. If there are multiple possible
* languages, the first one is returned. This method should only be used for
* test code or as a fallback since file extensions may match multiple
* {@link ELanguage}s.
*/
public static ELanguage fromPath(String path) {
return fromFile(new File(path));
}
/**
* Gets the {@link ELanguage} value corresponding to the file extension of the
* file. Returns null if no extension was found. If there are multiple possible
* languages, the first one is returned. This method should only be used for
* test code or as a fallback since file extensions may match multiple
* {@link ELanguage}s.
*/
public static ELanguage fromFile(File file) {
return fromFileExtension(FileSystemUtils.getFileExtension(file));
}
/**
* Gets the {@link ELanguage} value corresponding to the given file extension
* (without a dot). Returns {@link ELanguage#LINE} as a fallback if no language
* was registered for the extension. If there are multiple possible languages
* registered for the extension, however, the first one is returned.
*/
public static ELanguage fromFileExtension(String extension) {
if (extension == null) {
return ELanguage.LINE;
}
List result = EXTENSION_2_LANGUAGE_MAP.getCollection(extension.toLowerCase());
if (result == null || result.isEmpty()) {
return ELanguage.LINE;
}
return result.get(0);
}
/** Returns all languages for the given file extension */
public static Set getAllLanguagesForExtension(String extension) {
if (extension == null) {
return Collections.emptySet();
}
return new HashSet<>(EXTENSION_2_LANGUAGE_MAP.getCollectionOrEmpty(extension.toLowerCase()));
}
/**
* Returns all {@link ELanguage}s matching the file extension of the given file
* path.
*/
public static Set getAllLanguagesForPath(String path) {
return getAllLanguagesForExtension(FileSystemUtils.getFileExtension(path));
}
/** @return Whether the given language has the concept of methods. */
public static boolean languageHasMethods(ELanguage language) {
return !LANGUAGES_WITHOUT_METHODS.contains(language);
}
}