// Copyright 2017 Google Inc. // // 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 language contains methods and information about the different // programming languages the comment parser supports. package language import ( "path/filepath" "strings" ) // Language is the progamming language we're grabbing the comments from. type Language int // Languages we can retrieve comments from. const ( Unknown Language = iota AppleScript Assembly BLIF // Berkley Logic Interface Format Batch C Clif Clojure CMake CSharp Dart EDIF // Electronic Design Interchange Format Elixir Flex Fortran GLSLF // OpenGL Shading Language Go HTML Haskell Java JavaScript Kotlin LEF // Library Exchange Format Lisp Markdown Matlab MySQL NinjaBuild ObjectiveC Perl Python R Ruby Rust SDC // Synopsis Design Constraint SDF // Standard Delay Format SPEF // Standard Parasitics Exchange Format SQL SWIG Shader Shell Swift SystemVerilog TCL TypeScript Verilog XDC // Xilinx Design Constraint files Yacc Yaml ) // style is the comment styles that a language uses. type style int // Comment styles. const ( unknown style = iota applescript // -- ... and (* ... *) batch // @REM bcpl // // ... and /* ... */ cmake // # ... and #[[ ... ]] fortran // ! ... hash // # ... haskell // -- ... and {- ... -} html // lisp // ;; ... matlab // % ... mysql // # ... and /* ... */ ruby // # ... and =begin ... =end shell // # ... and %{ ... %} sql // -- ... and /* ... */ ) // ClassifyLanguage determines what language the source code was written in. It // does this by looking at the file's extension. func ClassifyLanguage(filename string) Language { ext := strings.ToLower(filepath.Ext(filename)) if len(ext) == 0 || ext[0] != '.' { return Unknown } switch ext[1:] { // Skip the '.'. case "applescript": return AppleScript case "bat": return Batch case "blif", "eblif": return BLIF case "c", "cc", "cpp", "c++", "h", "hh", "hpp": return C case "clif": return Clif case "cmake": return CMake case "cs": return CSharp case "dart": return Dart case "ex", "exs": return Elixir case "f", "f90", "f95": return Fortran case "glslf": return GLSLF case "go": return Go case "hs": return Haskell case "html", "htm", "ng", "sgml": return HTML case "java": return Java case "js": return JavaScript case "kt": return Kotlin case "l": return Flex case "lef": return LEF case "lisp", "el", "clj": return Lisp case "m", "mm": return ObjectiveC case "md": return Markdown case "gn": return NinjaBuild case "pl", "pm": return Perl case "py", "pi": return Python case "r": return R case "rb": return Ruby case "rs": return Rust case "s": return Assembly case "sdf": return SDF case "sh": return Shell case "shader": return Shader case "sql": return SQL case "swift": return Swift case "swig": return SWIG case "sv", "svh": return SystemVerilog case "tcl", "sdc", "xdc": return TCL case "ts", "tsx": return TypeScript case "v", "vh": return Verilog case "y": return Yacc case "yaml": return Yaml } return Unknown } // commentStyle returns the language's comment style. func (lang Language) commentStyle() style { switch lang { case Assembly, C, CSharp, Dart, Flex, GLSLF, Go, Java, JavaScript, Kotlin, ObjectiveC, Rust, Shader, Swift, SWIG, TypeScript, Yacc, Verilog, SystemVerilog, SDF, SPEF: return bcpl case Batch: return batch case BLIF, TCL: return hash case CMake: return cmake case Fortran: return fortran case Haskell: return haskell case HTML, Markdown: return html case Clojure, Lisp: return lisp case Ruby: return ruby case Clif, Elixir, NinjaBuild, Perl, Python, R, Shell, Yaml: return shell case Matlab: return matlab case MySQL: return mysql case SQL: return sql } return unknown } // SingleLineCommentStart returns the starting string of a single line comment // for the given language. There is no equivalent "End" method, because it's // the end of line. func (lang Language) SingleLineCommentStart() string { switch lang.commentStyle() { case applescript, haskell, sql: return "--" case batch: return "@REM" case bcpl: return "//" case fortran: return "!" case lisp: return ";" case matlab: return "%" case shell, ruby, cmake, mysql, hash: return "#" } return "" } // MultilineCommentStart returns the starting string of a multiline comment for // the given language. func (lang Language) MultilineCommentStart() string { switch lang.commentStyle() { case applescript: return "(*" case bcpl, mysql: if lang != Rust { return "/*" } case cmake: return "#[[" case haskell: return "{-" case html: return "" case matlab: return "%}" case ruby: return "=end" } return "" } // QuoteCharacter returns 'true' if the character is considered the beginning // of a string in the given language. The second return value is true if the // string allows for escaping. func (lang Language) QuoteCharacter(quote rune) (ok bool, escape bool) { switch quote { case '"', '\'': return true, true case '`': if lang == Go { return true, false } } return false, false } // NestedComments returns true if the language allows for nested multiline comments. func (lang Language) NestedComments() bool { return lang == Swift }