diff --git a/.rubocop.yml b/.rubocop.yml index f5b9e9f57a..3b768252e9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,6 +2,7 @@ inherit_from: .rubocop_todo.yml require: - ./lib/rubocop/cop/rouge/no_building_alternation_pattern_in_regexp.rb + - ./lib/rubocop/cop/rouge/no_huge_collections.rb plugins: - rubocop-performance @@ -18,6 +19,9 @@ AllCops: - "lib/rouge/lexers/**/builtins.rb" NewCops: enable +Rouge: + Enabled: true + Style: Enabled: false @@ -76,12 +80,41 @@ Lint/IneffectiveAccessModifier: Lint/AmbiguousOperatorPrecedence: Enabled: false +# this just is plain broken, disabling +Lint/OutOfRangeRegexpRef: + Enabled: false + +# there are actual reasons to do this +Lint/MissingSuper: + Enabled: false + +# sometimes the arguments are deprecated you guys +Lint/ToEnumArguments: + Enabled: false + +# sometimes we deal with very gnarly strings, this is not useful +Lint/NestedPercentLiteral: + Enabled: false + +# usually not actionable +Lint/DuplicateBranch: + Enabled: false + Naming/BlockForwarding: Enabled: false Naming/PredicateMethod: Enabled: false +Naming/MethodParameterName: + Enabled: false + +Naming/HeredocDelimiterNaming: + Enabled: false + +Naming/VariableNumber: + Enabled: false + Performance/RegexpMatch: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f8fd2ea29b..435edc5bf3 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,115 +1,23 @@ # This configuration was generated by # `rubocop --auto-gen-config --exclude-limit 50` -# on 2026-02-27 15:13:26 UTC using RuboCop version 1.85.0. +# on 2026-03-20 18:54:21 UTC using RuboCop version 1.84.2. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 8 -# Configuration parameters: AllowedMethods. -# AllowedMethods: enums -Lint/ConstantDefinitionInBlock: - Exclude: - - 'spec/formatters/html_spec.rb' - - 'spec/lexer_spec.rb' - - 'spec/theme_spec.rb' - -# Offense count: 38 -# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch. -Lint/DuplicateBranch: - Exclude: - - 'lib/rouge/cli.rb' - - 'lib/rouge/lexers/apache.rb' - - 'lib/rouge/lexers/apex.rb' - - 'lib/rouge/lexers/batchfile.rb' - - 'lib/rouge/lexers/brightscript.rb' - - 'lib/rouge/lexers/common_lisp.rb' - - 'lib/rouge/lexers/coq.rb' - - 'lib/rouge/lexers/css.rb' - - 'lib/rouge/lexers/cython.rb' - - 'lib/rouge/lexers/ecl.rb' - - 'lib/rouge/lexers/idlang.rb' - - 'lib/rouge/lexers/llvm.rb' - - 'lib/rouge/lexers/php.rb' - - 'lib/rouge/lexers/python.rb' - - 'lib/rouge/lexers/robot_framework.rb' - - 'lib/rouge/lexers/ruby.rb' - - 'lib/rouge/lexers/sas.rb' - - 'lib/rouge/lexers/sqf.rb' - - 'lib/rouge/lexers/stan.rb' - - 'lib/rouge/lexers/varnish.rb' - - 'lib/rouge/lexers/viml.rb' - - 'lib/rouge/lexers/yang.rb' - -# Offense count: 3 +# Offense count: 1 # Configuration parameters: AllowComments, AllowEmptyLambdas. Lint/EmptyBlock: Exclude: - 'lib/rouge/lexers/nix.rb' - - 'spec/lexers/terraform_spec.rb' - -# Offense count: 27 -# Configuration parameters: AllowedParentClasses. -Lint/MissingSuper: - Exclude: - - 'lib/rouge/cli.rb' - - 'lib/rouge/formatters/html_inline.rb' - - 'lib/rouge/formatters/html_legacy.rb' - - 'lib/rouge/formatters/html_line_highlighter.rb' - - 'lib/rouge/formatters/html_line_table.rb' - - 'lib/rouge/formatters/html_linewise.rb' - - 'lib/rouge/formatters/html_pygments.rb' - - 'lib/rouge/formatters/html_table.rb' - - 'lib/rouge/formatters/null.rb' - - 'lib/rouge/formatters/terminal256.rb' - - 'lib/rouge/formatters/tex.rb' - - 'lib/rouge/guesser.rb' - - 'lib/rouge/guessers/disambiguation.rb' - - 'lib/rouge/guessers/filename.rb' - - 'lib/rouge/guessers/glob_mapping.rb' - - 'lib/rouge/guessers/mimetype.rb' - - 'lib/rouge/guessers/modeline.rb' - - 'lib/rouge/guessers/source.rb' - - 'lib/rouge/regex_lexer.rb' - - 'lib/rouge/theme.rb' - - 'lib/rouge/util.rb' # Offense count: 4 -Lint/NestedPercentLiteral: - Exclude: - - 'lib/rouge/lexers/hylang.rb' - - 'lib/rouge/lexers/janet.rb' - - 'lib/rouge/lexers/powershell.rb' - - 'spec/lexers/j_spec.rb' - -# Offense count: 1 -Lint/OutOfRangeRegexpRef: - Exclude: - - 'lib/rouge/tex_theme_renderer.rb' - -# Offense count: 1 -Lint/ToEnumArguments: - Exclude: - - 'lib/rouge/lexer.rb' - -# Offense count: 43 Naming/ConstantName: Exclude: - 'lib/rouge/lexers/eiffel.rb' - - 'lib/rouge/themes/gruvbox.rb' - -# Offense count: 8 -# Configuration parameters: ForbiddenDelimiters. -# ForbiddenDelimiters: (?i-mx:(^|\s)(EO[A-Z]{1}|END)(\s|$)) -Naming/HeredocDelimiterNaming: - Exclude: - - 'lib/rouge/tex_theme_renderer.rb' - - 'spec/lexers/mason_spec.rb' - - 'spec/lexers/matlab_spec.rb' - - 'spec/lexers/swift_spec.rb' -# Offense count: 8 +# Offense count: 5 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyleForLeadingUnderscores. # SupportedStylesForLeadingUnderscores: disallowed, required, optional @@ -120,7 +28,6 @@ Naming/MemoizedInstanceVariableName: - 'lib/rouge/lexers/hack.rb' - 'lib/rouge/lexers/python.rb' - 'lib/rouge/lexers/verilog.rb' - - 'lib/rouge/lexers/yang.rb' # Offense count: 16 # Configuration parameters: EnforcedStyle, AllowedPatterns, ForbiddenIdentifiers, ForbiddenPatterns. @@ -131,35 +38,6 @@ Naming/MethodName: - 'lib/rouge/lexers/igorpro.rb' - 'lib/rouge/lexers/xpath.rb' -# Offense count: 68 -# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to -Naming/MethodParameterName: - Exclude: - - 'lib/rouge.rb' - - 'lib/rouge/cli.rb' - - 'lib/rouge/formatter.rb' - - 'lib/rouge/formatters/html.rb' - - 'lib/rouge/formatters/html_legacy.rb' - - 'lib/rouge/formatters/html_line_table.rb' - - 'lib/rouge/formatters/html_linewise.rb' - - 'lib/rouge/formatters/html_pygments.rb' - - 'lib/rouge/formatters/html_table.rb' - - 'lib/rouge/formatters/null.rb' - - 'lib/rouge/formatters/terminal256.rb' - - 'lib/rouge/formatters/tex.rb' - - 'lib/rouge/guessers/disambiguation.rb' - - 'lib/rouge/lexer.rb' - - 'lib/rouge/lexers/coq.rb' - - 'lib/rouge/lexers/escape.rb' - - 'lib/rouge/lexers/plain_text.rb' - - 'lib/rouge/regex_lexer.rb' - - 'lib/rouge/tex_theme_renderer.rb' - - 'lib/rouge/theme.rb' - - 'lib/rouge/token.rb' - - 'lib/rouge/util.rb' - - 'spec/support/lexing.rb' - # Offense count: 40 # Configuration parameters: EnforcedStyle, AllowedIdentifiers, AllowedPatterns, ForbiddenIdentifiers, ForbiddenPatterns. # SupportedStyles: snake_case, camelCase @@ -172,15 +50,6 @@ Naming/VariableName: - 'lib/rouge/lexers/kotlin.rb' - 'lib/rouge/lexers/xpath.rb' -# Offense count: 5 -# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. -# SupportedStyles: snake_case, normalcase, non_integer -# AllowedIdentifiers: TLS1_1, TLS1_2, capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64 -Naming/VariableNumber: - Exclude: - - 'lib/rouge/lexers/c.rb' - - 'lib/rouge/themes/gruvbox.rb' - # Offense count: 2 # This cop supports unsafe autocorrection (--autocorrect-all). Performance/StringInclude: @@ -230,3 +99,23 @@ Rouge/NoBuildingAlternationPatternInRegexp: - 'lib/rouge/lexers/vala.rb' - 'lib/rouge/lexers/wollok.rb' - 'lib/rouge/lexers/xojo.rb' + +# Offense count: 20 +Rouge/NoHugeCollections: + Exclude: + - 'lib/rouge/lexers/apple_script.rb' + - 'lib/rouge/lexers/cobol.rb' + - 'lib/rouge/lexers/common_lisp.rb' + - 'lib/rouge/lexers/css.rb' + - 'lib/rouge/lexers/datastudio.rb' + - 'lib/rouge/lexers/freefem.rb' + - 'lib/rouge/lexers/hql.rb' + - 'lib/rouge/lexers/idlang.rb' + - 'lib/rouge/lexers/igorpro.rb' + - 'lib/rouge/lexers/janet.rb' + - 'lib/rouge/lexers/openedge.rb' + - 'lib/rouge/lexers/plsql.rb' + - 'lib/rouge/lexers/racket.rb' + - 'lib/rouge/lexers/sas.rb' + - 'lib/rouge/lexers/sql.rb' + - 'lib/rouge/lexers/stata.rb' diff --git a/lib/rouge/cli.rb b/lib/rouge/cli.rb index ef305251bc..3a5e706610 100644 --- a/lib/rouge/cli.rb +++ b/lib/rouge/cli.rb @@ -514,9 +514,7 @@ def run out = [] argv.each do |arg| case arg - when /^(--\w+)=(.*)$/ - out << $1 << $2 - when /^(-\w)(.+)$/ + when /^(--\w+)=(.*)$/, /^(-\w)(.+)$/ out << $1 << $2 else out << arg diff --git a/lib/rouge/demos/abap b/lib/rouge/demos/abap index 1f0171bb91..2ddc1a41ab 100644 --- a/lib/rouge/demos/abap +++ b/lib/rouge/demos/abap @@ -1,6 +1,30 @@ -lo_obj ?= lo_obj->do_nothing( 'Char' && ` String` ). +DATA(lo_obj) = new zcl_obj_factory( + EXPORTING + input = |some nice string| +) +DATA(lo_subobj) ?= lo_obj->do_nothing( 'Char' && ` String` ). -SELECT SINGLE * FROM mara INTO ls_mara WHERE matkl EQ '1324'. -LOOP AT lt_mara ASSIGNING . - CHECK -mtart EQ '0001'. +SELECT SINGLE matnr, matkl, mtart, maktx + FROM mara + INNER JOIN makt + ON makt~matnr EQ mara~matnr + INTO @data(ls_mara) + WHERE matkl EQ '1324' + AND spras EQ @sy-langu. + +LOOP AT lt_mara ASSIGNING FIELD-SYMBOL(). + CHECK -mtart = '0001'. ENDLOOP. + +CALL FUNCTION 'DO_NOTHING' + EXPORTING + input = 'input' + IMPORTING + output = 'output' + CHANGING + to_change = lv_some_variable + TABLES + table_to_change = lt_some_table + EXCEPTIONS + ERROR = 1 + OTHERS = 2. diff --git a/lib/rouge/lexers/abap.rb b/lib/rouge/lexers/abap.rb index 8be9e950ce..a2be996f40 100644 --- a/lib/rouge/lexers/abap.rb +++ b/lib/rouge/lexers/abap.rb @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- # # frozen_string_literal: true -# ABAP elements taken from http://help.sap.com/abapdocu_750/en/index.htm?file=abapdo.htm - module Rouge module Lexers class ABAP < RegexLexer @@ -12,174 +10,14 @@ class ABAP < RegexLexer filenames '*.abap' mimetypes 'text/x-abap' - def self.keywords - @keywords = Set.new %w( - *-INPUT ?TO ABAP-SOURCE ABBREVIATED ABS ABSTRACT ACCEPT ACCEPTING - ACCORDING ACCP ACTIVATION ACTUAL ADD ADD-CORRESPONDING ADJACENT - AFTER ALIAS ALIASES ALIGN ALL ALLOCATE ALPHA ANALYSIS ANALYZER AND - ANY APPEND APPENDAGE APPENDING APPLICATION ARCHIVE AREA ARITHMETIC - AS ASCENDING ASPECT ASSERT ASSIGN ASSIGNED ASSIGNING ASSOCIATION - ASYNCHRONOUS AT ATTRIBUTES AUTHORITY AUTHORITY-CHECK AVG BACK - BACKGROUND BACKUP BACKWARD BADI BASE BEFORE BEGIN BETWEEN BIG BINARY - BINTOHEX BIT BIT-AND BIT-NOT BIT-OR BIT-XOR BLACK BLANK BLANKS BLOB - BLOCK BLOCKS BLUE BOUND BOUNDARIES BOUNDS BOXED BREAK-POINT BT - BUFFER BY BYPASSING BYTE BYTE-CA BYTE-CN BYTE-CO BYTE-CS BYTE-NA - BYTE-NS BYTE-ORDER CA CALL CALLING CASE CAST CASTING CATCH CEIL - CENTER CENTERED CHAIN CHAIN-INPUT CHAIN-REQUEST CHANGE CHANGING - CHANNELS CHAR CHAR-TO-HEX CHARACTER CHECK CHECKBOX CIRCULAR CLASS - CLASS-CODING CLASS-DATA CLASS-EVENTS CLASS-METHODS CLASS-POOL - CLEANUP CLEAR CLIENT CLNT CLOB CLOCK CLOSE CN CO COALESCE CODE - CODING COLLECT COLOR COLUMN COLUMNS COL_BACKGROUND COL_GROUP - COL_HEADING COL_KEY COL_NEGATIVE COL_NORMAL COL_POSITIVE COL_TOTAL - COMMENT COMMENTS COMMIT COMMON COMMUNICATION COMPARING COMPONENT - COMPONENTS COMPRESSION COMPUTE CONCAT CONCATENATE CONCAT_WITH_SPACE - COND CONDENSE CONDITION CONNECT CONNECTION CONSTANTS CONTEXT - CONTEXTS CONTINUE CONTROL CONTROLS CONV CONVERSION CONVERT COPIES - COPY CORRESPONDING COUNT COUNTRY COVER CP CPI CREATE CREATING - CRITICAL CS CUKY CURR CURRENCY CURRENCY_CONVERSION CURRENT CURSOR - CURSOR-SELECTION CUSTOMER CUSTOMER-FUNCTION CX_DYNAMIC_CHECK - CX_NO_CHECK CX_ROOT CX_SQL_EXCEPTION CX_STATIC_CHECK DANGEROUS DATA - DATABASE DATAINFO DATASET DATE DATS DATS_ADD_DAYS DATS_ADD_MONTHS - DATS_DAYS_BETWEEN DATS_IS_VALID DAYLIGHT DD/MM/YY DD/MM/YYYY DDMMYY - DEALLOCATE DEC DECIMALS DECIMAL_SHIFT DECLARATIONS DEEP DEFAULT - DEFERRED DEFINE DEFINING DEFINITION DELETE DELETING DEMAND - DEPARTMENT DESCENDING DESCRIBE DESTINATION DETAIL DF16_DEC DF16_RAW - DF16_SCL DF34_DEC DF34_RAW DF34_SCL DIALOG DIRECTORY DISCONNECT - DISPLAY DISPLAY-MODE DISTANCE DISTINCT DIV DIVIDE - DIVIDE-CORRESPONDING DIVISION DO DUMMY DUPLICATE DUPLICATES DURATION - DURING DYNAMIC DYNPRO E EDIT EDITOR-CALL ELSE ELSEIF EMPTY ENABLED - ENABLING ENCODING END END-ENHANCEMENT-SECTION END-LINES - END-OF-DEFINITION END-OF-FILE END-OF-PAGE END-OF-SELECTION - END-TEST-INJECTION END-TEST-SEAM ENDAT ENDCASE ENDCATCH ENDCHAIN - ENDCLASS ENDDO ENDENHANCEMENT ENDEXEC ENDFORM ENDFUNCTION ENDIAN - ENDIF ENDING ENDINTERFACE ENDLOOP ENDMETHOD ENDMODULE ENDON - ENDPROVIDE ENDSELECT ENDTRY ENDWHILE ENDWITH ENGINEERING ENHANCEMENT - ENHANCEMENT-POINT ENHANCEMENT-SECTION ENHANCEMENTS ENTRIES ENTRY - ENVIRONMENT EQ EQUIV ERRORMESSAGE ERRORS ESCAPE ESCAPING EVENT - EVENTS EXACT EXCEPT EXCEPTION EXCEPTION-TABLE EXCEPTIONS EXCLUDE - EXCLUDING EXEC EXECUTE EXISTS EXIT EXIT-COMMAND EXPAND EXPANDING - EXPIRATION EXPLICIT EXPONENT EXPORT EXPORTING EXTEND EXTENDED - EXTENSION EXTRACT FAIL FETCH FIELD FIELD-GROUPS FIELD-SYMBOL - FIELD-SYMBOLS FIELDS FILE FILTER FILTER-TABLE FILTERS FINAL FIND - FIRST FIRST-LINE FIXED-POINT FKEQ FKGE FLOOR FLTP FLUSH FONT FOR - FORM FORMAT FORWARD FOUND FRAME FRAMES FREE FRIENDS FROM FUNCTION - FUNCTION-POOL FUNCTIONALITY FURTHER GAPS GE GENERATE GET - GET_PRINT_PARAMETERS GIVING GKEQ GKGE GLOBAL GRANT GREEN GROUP - GROUPS GT HANDLE HANDLER HARMLESS HASHED HAVING HDB HEAD-LINES - HEADER HEADERS HEADING HELP-ID HELP-REQUEST HEXTOBIN HIDE HIGH HINT - HOLD HOTSPOT I ICON ID IDENTIFICATION IDENTIFIER IDS IF - IF_ABAP_CLOSE_RESOURCE IF_ABAP_CODEPAGE IF_ABAP_DB_BLOB_HANDLE - IF_ABAP_DB_CLOB_HANDLE IF_ABAP_DB_LOB_HANDLE IF_ABAP_DB_READER - IF_ABAP_DB_WRITER IF_ABAP_READER IF_ABAP_WRITER IF_MESSAGE - IF_OS_CA_INSTANCE IF_OS_CA_PERSISTENCY IF_OS_FACTORY IF_OS_QUERY - IF_OS_QUERY_MANAGER IF_OS_QUERY_OPTIONS IF_OS_STATE - IF_OS_TRANSACTION IF_OS_TRANSACTION_MANAGER IF_SERIALIZABLE_OBJECT - IF_SHM_BUILD_INSTANCE IF_SYSTEM_UUID IF_T100_DYN_MSG IF_T100_MESSAGE - IGNORE IGNORING IMMEDIATELY IMPLEMENTATION IMPLEMENTATIONS - IMPLEMENTED IMPLICIT IMPORT IMPORTING IN INACTIVE INCL INCLUDE - INCLUDES INCLUDING INCREMENT INDEX INDEX-LINE INFOTYPES INHERITING - INIT INITIAL INITIALIZATION INNER INOUT INPUT INSERT INSTANCE - INSTANCES INSTR INT1 INT2 INT4 INT8 INTENSIFIED INTERFACE - INTERFACE-POOL INTERFACES INTERNAL INTERVALS INTO INVERSE - INVERTED-DATE IS ISO ITNO JOB JOIN KEEP KEEPING KERNEL KEY KEYS - KEYWORDS KIND LANG LANGUAGE LAST LATE LAYOUT LCHR LDB_PROCESS LE - LEADING LEAVE LEFT LEFT-JUSTIFIED LEFTPLUS LEFTSPACE LEGACY LENGTH - LET LEVEL LEVELS LIKE LINE LINE-COUNT LINE-SELECTION LINE-SIZE - LINEFEED LINES LIST LIST-PROCESSING LISTBOX LITTLE LLANG LOAD - LOAD-OF-PROGRAM LOB LOCAL LOCALE LOCATOR LOG-POINT LOGFILE LOGICAL - LONG LOOP LOW LOWER LPAD LPI LRAW LT LTRIM M MAIL MAIN MAJOR-ID - MAPPING MARGIN MARK MASK MATCH MATCHCODE MAX MAXIMUM MEDIUM MEMBERS - MEMORY MESH MESSAGE MESSAGE-ID MESSAGES MESSAGING METHOD METHODS MIN - MINIMUM MINOR-ID MM/DD/YY MM/DD/YYYY MMDDYY MOD MODE MODIF MODIFIER - MODIFY MODULE MOVE MOVE-CORRESPONDING MULTIPLY - MULTIPLY-CORRESPONDING NA NAME NAMETAB NATIVE NB NE NESTED NESTING - NEW NEW-LINE NEW-PAGE NEW-SECTION NEXT NO NO-DISPLAY NO-EXTENSION - NO-GAP NO-GAPS NO-GROUPING NO-HEADING NO-SCROLLING NO-SIGN NO-TITLE - NO-TOPOFPAGE NO-ZERO NODE NODES NON-UNICODE NON-UNIQUE NOT NP NS - NULL NUMBER NUMC O OBJECT OBJECTS OBLIGATORY OCCURRENCE OCCURRENCES - OCCURS OF OFF OFFSET ON ONLY OPEN OPTION OPTIONAL OPTIONS OR ORDER - OTHER OTHERS OUT OUTER OUTPUT OUTPUT-LENGTH OVERFLOW OVERLAY PACK - PACKAGE PAD PADDING PAGE PAGES PARAMETER PARAMETER-TABLE PARAMETERS - PART PARTIALLY PATTERN PERCENTAGE PERFORM PERFORMING PERSON PF - PF-STATUS PINK PLACES POOL POSITION POS_HIGH POS_LOW PRAGMAS PREC - PRECOMPILED PREFERRED PRESERVING PRIMARY PRINT PRINT-CONTROL - PRIORITY PRIVATE PROCEDURE PROCESS PROGRAM PROPERTY PROTECTED - PROVIDE PUBLIC PUSH PUSHBUTTON PUT QUAN QUEUE-ONLY QUICKINFO - RADIOBUTTON RAISE RAISING RANGE RANGES RAW RAWSTRING READ READ-ONLY - READER RECEIVE RECEIVED RECEIVER RECEIVING RED REDEFINITION REDUCE - REDUCED REF REFERENCE REFRESH REGEX REJECT REMOTE RENAMING REPLACE - REPLACEMENT REPLACING REPORT REQUEST REQUESTED RESERVE RESET - RESOLUTION RESPECTING RESPONSIBLE RESULT RESULTS RESUMABLE RESUME - RETRY RETURN RETURNCODE RETURNING RETURNS RIGHT RIGHT-JUSTIFIED - RIGHTPLUS RIGHTSPACE RISK RMC_COMMUNICATION_FAILURE - RMC_INVALID_STATUS RMC_SYSTEM_FAILURE ROLE ROLLBACK ROUND ROWS RPAD - RTRIM RUN SAP SAP-SPOOL SAVING SCALE_PRESERVING - SCALE_PRESERVING_SCIENTIFIC SCAN SCIENTIFIC - SCIENTIFIC_WITH_LEADING_ZERO SCREEN SCROLL SCROLL-BOUNDARY SCROLLING - SEARCH SECONDARY SECONDS SECTION SELECT SELECT-OPTIONS SELECTION - SELECTION-SCREEN SELECTION-SET SELECTION-SETS SELECTION-TABLE - SELECTIONS SEND SEPARATE SEPARATED SET SHARED SHIFT SHORT - SHORTDUMP-ID SIGN SIGN_AS_POSTFIX SIMPLE SINGLE SIZE SKIP SKIPPING - SMART SOME SORT SORTABLE SORTED SOURCE SPACE SPECIFIED SPLIT SPOOL - SPOTS SQL SQLSCRIPT SSTRING STABLE STAMP STANDARD START-OF-SELECTION - STARTING STATE STATEMENT STATEMENTS STATIC STATICS STATUSINFO - STEP-LOOP STOP STRING STRUCTURE STRUCTURES STYLE SUBKEY SUBMATCHES - SUBMIT SUBROUTINE SUBSCREEN SUBSTRING SUBTRACT - SUBTRACT-CORRESPONDING SUFFIX SUM SUMMARY SUMMING SUPPLIED SUPPLY - SUPPRESS SWITCH SWITCHSTATES SYMBOL SYNCPOINTS SYNTAX SYNTAX-CHECK - SYNTAX-TRACE SYST SYSTEM-CALL SYSTEM-EXCEPTIONS SYSTEM-EXIT TAB - TABBED TABLE TABLES TABLEVIEW TABSTRIP TARGET TASK TASKS TEST - TEST-INJECTION TEST-SEAM TESTING TEXT TEXTPOOL THEN THROW TIME TIMES - TIMESTAMP TIMEZONE TIMS TIMS_IS_VALID TITLE TITLE-LINES TITLEBAR TO - TOKENIZATION TOKENS TOP-LINES TOP-OF-PAGE TRACE-FILE TRACE-TABLE - TRAILING TRANSACTION TRANSFER TRANSFORMATION TRANSLATE TRANSPORTING - TRMAC TRUNCATE TRUNCATION TRY TSTMP_ADD_SECONDS - TSTMP_CURRENT_UTCTIMESTAMP TSTMP_IS_VALID TSTMP_SECONDS_BETWEEN TYPE - TYPE-POOL TYPE-POOLS TYPES ULINE UNASSIGN UNDER UNICODE UNION UNIQUE - UNIT UNIT_CONVERSION UNIX UNPACK UNTIL UNWIND UP UPDATE UPPER USER - USER-COMMAND USING UTF-8 VALID VALUE VALUE-REQUEST VALUES VARC VARY - VARYING VERIFICATION-MESSAGE VERSION VIA VIEW VISIBLE WAIT WARNING - WHEN WHENEVER WHERE WHILE WIDTH WINDOW WINDOWS WITH WITH-HEADING - WITH-TITLE WITHOUT WORD WORK WRITE WRITER XML XSD YELLOW YES YYMMDD - Z ZERO ZONE - ) - end - - def self.builtins - @keywords = Set.new %w( - acos apply asin assign atan attribute bit-set boolc boolx call - call-method cast ceil cfunc charlen char_off class_constructor clear - cluster cmax cmin cnt communication_failure concat_lines_of cond - cond-var condense constructor contains contains_any_not_of - contains_any_of copy cos cosh count count_any_not_of count_any_of - create cursor data dbmaxlen dbtab deserialize destructor distance - empty error_message escape exp extensible find find_any_not_of - find_any_of find_end floor frac from_mixed group hashed header idx - include index insert ipow itab key lax lines line_exists line_index - log log10 loop loop_key match matches me mesh_path namespace nmax - nmin node numeric numofchar object parameter primary_key read ref - repeat replace rescale resource_failure reverse root round segment - sender serialize shift_left shift_right sign simple sin sinh skip - sorted space sqrt standard strlen substring substring_after - substring_before substring_from substring_to sum switch switch-var - system_failure table table_line tan tanh template text to_lower - to_mixed to_upper transform translate trunc type value variable write - xsdbool xsequence xstrlen - ) - end + lazy { require_relative 'abap/builtins' } - def self.types - @types = Set.new %w( - b c d decfloat16 decfloat34 f i int8 n p s t x - clike csequence decfloat string xstring - ) - end + TYPES = Set.new %w( + b c d decfloat16 decfloat34 f i int8 n p s t x + clike csequence decfloat string xstring + ) - def self.new_keywords - @types = Set.new %w( - DATA FIELD-SYMBOL - ) - end + NEW_KEYWORDS = Set.new %w(DATA FIELD-SYMBOL) state :root do rule %r/\s+/m, Text @@ -187,30 +25,78 @@ def self.new_keywords rule %r/".*/, Comment::Single rule %r(^\*.*), Comment::Multiline rule %r/\d+/, Num::Integer + + # String templates |...| + rule %r/\|/, Str::Interpol, :string_template + rule %r/('|`)/, Str::Single, :single_string - rule %r/[\[\]\(\)\{\}\.,:\|]/, Punctuation + + # CDS annotations: @KEYWORD.field + rule %r/(@)([A-Z][A-Za-z0-9_]*)(\.)([A-Za-z][A-Za-z0-9_]*)/ do |m| + token Operator, m[1] + if KEYWORDS.include? m[2].upcase + token Keyword, m[2] + else + token Name, m[2] + end + token Punctuation, m[3] + token Name, m[4] + end + + # structure field access with dot (table.field should not highlight field as keyword) + # This must come before the general punctuation rule + # In dot-access patterns, treat both parts as names (even if they match keywords) + rule %r/([A-Za-z][A-Za-z0-9_]*)(\.)([A-Za-z][A-Za-z0-9_]*)/ do |m| + token Name, m[1] + token Punctuation, m[2] + token Name, m[3] + end + # Parameter names in function/method interfaces (word before =) + # Matches word followed by optional whitespace and = + # This handles EXPORTING/IMPORTING/CHANGING/TABLES/USING parameter names + rule %r/([A-Za-z][A-Za-z0-9_]*)(?=\s*=)/ do |m| + token Name, m[1] + end + rule %r/[\[\]\(\)\{\}\.,:]/, Punctuation # builtins / new ABAP 7.40 keywords (@DATA(), ...) rule %r/(->|=>)?([A-Za-z][A-Za-z0-9_\-]*)(\()/ do |m| - if m[1] != '' - token Operator, m[1] - end + token Operator, m[1] + + word = m[2] - if (self.class.new_keywords.include? m[2].upcase) && m[1].nil? + if (NEW_KEYWORDS.include? word.upcase) && m[1].nil? token Keyword, m[2] - elsif (self.class.builtins.include? m[2].downcase) && m[1].nil? + elsif (BUILTINS.include? word.downcase) && m[1].nil? token Name::Builtin, m[2] else token Name, m[2] end + token Punctuation, m[3] end + # hyphenated keywords (like NON-UNIQUE) + rule %r/[A-Za-z][A-Za-z0-9_]*(-[A-Za-z][A-Za-z0-9_]*)+/ do |m| + if KEYWORDS.include? m[0].upcase + token Keyword + else + token Name + end + end + + # structure component access (variable-component should not be highlighted as keyword) + # this rule matches: word-word where the second part is lowercase or starts lowercase + rule %r/[A-Za-z][A-Za-z0-9_]*-[a-z][A-Za-z0-9_]*/, Name + + # variable names starting with $ (like $session) + rule %r/\$[A-Za-z][A-Za-z0-9_]*/, Name + # keywords, types and normal text rule %r/\w\w*/ do |m| - if self.class.keywords.include? m[0].upcase + if KEYWORDS.include? m[0].upcase token Keyword - elsif self.class.types.include? m[0].downcase + elsif TYPES.include? m[0].downcase token Keyword::Type else token Name @@ -235,6 +121,12 @@ def self.new_keywords rule %r/[^\\'`]+/, Str::Single end + state :string_template do + rule %r/\{[^}]*\}/, Str::Interpol # embedded expressions + rule %r/\|/, Str::Interpol, :pop! + rule %r/[^|{]+/, Str::Interpol + end + end end end diff --git a/lib/rouge/lexers/abap/builtins.rb b/lib/rouge/lexers/abap/builtins.rb new file mode 100644 index 0000000000..cd6851fdf5 --- /dev/null +++ b/lib/rouge/lexers/abap/builtins.rb @@ -0,0 +1,167 @@ +# ABAP elements taken from http://help.sap.com/abapdocu_750/en/index.htm?file=abapdo.htm +# Updated with modern ABAP 7.40+ and CDS keywords from ABAP 7.58 documentation +# +# This file is manually maintained by Manuel Laggner +# +# Please contact them with any requests for updates. + +module Rouge + module Lexers + class ABAP + KEYWORDS = Set.new %w( + *-INPUT ?TO ABAP-SOURCE ABBREVIATED ABS ABSTRACT ACCEPT ACCEPTING + ACCORDING ACCP ACTIVATION ACTUAL ADD ADD-CORRESPONDING ADJACENT + AFTER ALIAS ALIASES ALIGN ALL ALLOCATE ALPHA ANALYSIS ANALYZER AND + ANNOTATION ANNOTATIONS ANY APPEND APPENDAGE APPENDING APPLICATION + ARCHIVE AREA ARITHMETIC AS ASCENDING ASPECT ASSERT ASSIGN ASSIGNED + ASSIGNING ASSOCIATION ASSOCIATIONS ASYNCHRONOUS AT ATTRIBUTES + AUTHORITY AUTHORITY-CHECK AVG BACK BACKGROUND BACKUP BACKWARD BADI + BASE BEFORE BEGIN BETWEEN BIG BINARY BINTOHEX BIT BIT-AND BIT-NOT + BIT-OR BIT-XOR BLACK BLANK BLANKS BLOB BLOCK BLOCKS BLUE BOUND + BOUNDARIES BOUNDS BOXED BREAK-POINT BT BUFFER BY BYPASSING BYTE + BYTE-CA BYTE-CN BYTE-CO BYTE-CS BYTE-NA BYTE-NS BYTE-ORDER CA CALL + CALLING CASE CAST CASTING CATCH CEIL CENTER CENTERED CHAIN + CHAIN-INPUT CHAIN-REQUEST CHANGE CHANGING CHANNELS CHAR CHAR-TO-HEX + CHARACTER CHECK CHECKBOX CIRCULAR CLASS CLASS-CODING CLASS-DATA + CLASS-EVENTS CLASS-METHODS CLASS-POOL CLEANUP CLEAR CLIENT CLNT CLOB + CLOCK CLOSE CN CO COALESCE CODE CODING COLLECT COLOR COLUMN COLUMNS + COL_BACKGROUND COL_GROUP COL_HEADING COL_KEY COL_NEGATIVE COL_NORMAL + COL_POSITIVE COL_TOTAL COMMENT COMMENTS COMMIT COMMON COMMUNICATION + COMPARING COMPONENT COMPONENTS COMPOSITION COMPRESSION COMPUTE + CONCAT CONCATENATE CONCAT_WITH_SPACE COND CONDENSE CONDITION CONNECT + CONNECTION CONSTANTS CONTEXT CONTEXTS CONTINUE CONTROL CONTROLS CONV + CONVERSION CONVERT COPIES COPY CORRESPONDING COUNT COUNTRY COVER CP + CPI CREATE CREATING CRITICAL CS CUKY CURR CURRENCY + CURRENCY_CONVERSION CURRENT CURSOR CURSOR-SELECTION CUSTOMER + CUSTOMER-FUNCTION CX_DYNAMIC_CHECK CX_NO_CHECK CX_ROOT + CX_SQL_EXCEPTION CX_STATIC_CHECK DANGEROUS DATA DATABASE DATAINFO + DATASET DATE DATS DATS_ADD_DAYS DATS_ADD_MONTHS DATS_DAYS_BETWEEN + DATS_IS_VALID DAYLIGHT DD/MM/YY DD/MM/YYYY DDMMYY DEALLOCATE DEC + DECIMALS DECIMAL_SHIFT DECLARATIONS DEEP DEFAULT DEFERRED DEFINE + DEFINING DEFINITION DELETE DELETING DEMAND DEPARTMENT DESCENDING + DESCRIBE DESTINATION DETAIL DF16_DEC DF16_RAW DF16_SCL DF34_DEC + DF34_RAW DF34_SCL DIALOG DIRECTORY DISCONNECT DISPLAY DISPLAY-MODE + DISTANCE DISTINCT DIV DIVIDE DIVIDE-CORRESPONDING DIVISION DO DUMMY + DUPLICATE DUPLICATES DURATION DURING DYNAMIC DYNPRO E EDIT + EDITOR-CALL ELSE ELSEIF EMPTY ENABLED ENABLING ENCODING END + END-ENHANCEMENT-SECTION END-LINES END-OF-DEFINITION END-OF-FILE + END-OF-PAGE END-OF-SELECTION END-TEST-INJECTION END-TEST-SEAM ENDAT + ENDCASE ENDCATCH ENDCHAIN ENDCLASS ENDDO ENDENHANCEMENT ENDEXEC + ENDFORM ENDFUNCTION ENDIAN ENDIF ENDING ENDINTERFACE ENDLOOP + ENDMETHOD ENDMODULE ENDON ENDPROVIDE ENDSELECT ENDTRY ENDWHILE + ENDWITH ENGINEERING ENHANCEMENT ENHANCEMENT-POINT ENHANCEMENT-SECTION + ENHANCEMENTS ENTITIES ENTITY ENTRIES ENTRY ENUM ENVIRONMENT EQ EQUIV + ERRORMESSAGE ERRORS ESCAPE ESCAPING EVENT EVENTS EXACT EXCEPT + EXCEPTION EXCEPTION-TABLE EXCEPTIONS EXCLUDE EXCLUDING EXEC EXECUTE + EXISTS EXIT EXIT-COMMAND EXPAND EXPANDING EXPIRATION EXPLICIT + EXPONENT EXPORT EXPORTING EXTEND EXTENDED EXTENSION EXTRACT FAIL + FETCH FIELD FIELD-GROUPS FIELD-SYMBOL FIELD-SYMBOLS FIELDS FILE + FILTER FILTER-TABLE FILTERS FINAL FIND FIRST FIRST-LINE FIXED-POINT + FKEQ FKGE FLOOR FLTP FLUSH FONT FOR FORM FORMAT FORWARD FOUND FRAME + FRAMES FREE FRIENDS FROM FUNCTION FUNCTION-POOL FUNCTIONALITY + FURTHER GAPS GE GENERATE GET GET_PRINT_PARAMETERS GIVING GKEQ GKGE + GLOBAL GRANT GREEN GROUP GROUPS GT HANDLE HANDLER HARMLESS HASHED + HAVING HDB HEAD-LINES HEADER HEADERS HEADING HELP-ID HELP-REQUEST + HEXTOBIN HIDE HIGH HINT HOLD HOTSPOT I ICON ID IDENTIFICATION + IDENTIFIER IDS IF IF_ABAP_CLOSE_RESOURCE IF_ABAP_CODEPAGE + IF_ABAP_DB_BLOB_HANDLE IF_ABAP_DB_CLOB_HANDLE IF_ABAP_DB_LOB_HANDLE + IF_ABAP_DB_READER IF_ABAP_DB_WRITER IF_ABAP_READER IF_ABAP_WRITER + IF_MESSAGE IF_OS_CA_INSTANCE IF_OS_CA_PERSISTENCY IF_OS_FACTORY + IF_OS_QUERY IF_OS_QUERY_MANAGER IF_OS_QUERY_OPTIONS IF_OS_STATE + IF_OS_TRANSACTION IF_OS_TRANSACTION_MANAGER IF_SERIALIZABLE_OBJECT + IF_SHM_BUILD_INSTANCE IF_SYSTEM_UUID IF_T100_DYN_MSG IF_T100_MESSAGE + IGNORE IGNORING IMMEDIATELY IMPLEMENTATION IMPLEMENTATIONS + IMPLEMENTED IMPLICIT IMPORT IMPORTING IN INACTIVE INCL INCLUDE + INCLUDES INCLUDING INCREMENT INDEX INDEX-LINE INFOTYPES INHERITING + INIT INITIAL INITIALIZATION INNER INOUT INPUT INSERT INSTANCE + INSTANCES INSTR INT1 INT2 INT4 INT8 INTENSIFIED INTERFACE + INTERFACE-POOL INTERFACES INTERNAL INTERVALS INTO INVERSE + INVERTED-DATE IS ISO ITNO JOB JOIN KEEP KEEPING KERNEL KEY KEYS + KEYWORDS KIND LANG LANGUAGE LAST LATE LAYOUT LCHR LDB_PROCESS LE + LEADING LEAVE LEFT LEFT-JUSTIFIED LEFTPLUS LEFTSPACE LEGACY LENGTH + LET LEVEL LEVELS LIKE LINE LINE-COUNT LINE-SELECTION LINE-SIZE + LINEFEED LINES LIST LIST-PROCESSING LISTBOX LITTLE LLANG LOAD + LOAD-OF-PROGRAM LOB LOCAL LOCALE LOCATOR LOG-POINT LOGFILE LOGICAL + LONG LOOP LOW LOWER LPAD LPI LRAW LT LTRIM M MAIL MAIN MAJOR-ID MANY + MAPPING MARGIN MARK MASK MATCH MATCHCODE MAX MAXIMUM MEDIUM MEMBERS + MEMORY MESH MESSAGE MESSAGE-ID MESSAGES MESSAGING METHOD METHODS MIN + MINIMUM MINOR-ID MM/DD/YY MM/DD/YYYY MMDDYY MOD MODE MODIF MODIFIER + MODIFY MODULE MOVE MOVE-CORRESPONDING MULTIPLY + MULTIPLY-CORRESPONDING NA NAME NAMETAB NATIVE NB NE NESTED NESTING + NEW NEW-LINE NEW-PAGE NEW-SECTION NEXT NO NO-DISPLAY NO-EXTENSION + NO-GAP NO-GAPS NO-GROUPING NO-HEADING NO-SCROLLING NO-SIGN NO-TITLE + NO-TOPOFPAGE NO-ZERO NODE NODES NON-UNICODE NON-UNIQUE NOT NP NS + NULL NUMBER NUMC O OBJECT OBJECTS OBLIGATORY OCCURRENCE OCCURRENCES + OCCURS OF OFF OFFSET ON ONE ONLY OPEN OPTION OPTIONAL OPTIONS OR + ORDER OTHER OTHERS OUT OUTER OUTPUT OUTPUT-LENGTH OVERFLOW OVERLAY + PACK PACKAGE PAD PADDING PAGE PAGES PARAMETER PARAMETER-TABLE + PARAMETERS PART PARTIALLY PATTERN PERCENTAGE PERFORM PERFORMING + PERSON PF PF-STATUS PINK PLACES POOL POSITION POS_HIGH POS_LOW + PRAGMAS PREC PRECOMPILED PREFERRED PRESERVING PRIMARY PRINT + PRINT-CONTROL PRIORITY PRIVATE PROCEDURE PROCESS PROGRAM PROPERTY + PROTECTED PROVIDE PUBLIC PUSH PUSHBUTTON PUT QUAN QUEUE-ONLY + QUICKINFO RADIOBUTTON RAISE RAISING RANGE RANGES RAW RAWSTRING READ + READ-ONLY READER RECEIVE RECEIVED RECEIVER RECEIVING RED REDEFINITION + REDUCE REDUCED REF REFERENCE REFRESH REGEX REJECT REMOTE RENAMING + REPLACE REPLACEMENT REPLACING REPORT REQUEST REQUESTED RESERVE RESET + RESOLUTION RESPECTING RESPONSIBLE RESULT RESULTS RESUMABLE RESUME + RETRY RETURN RETURNCODE RETURNING RETURNS RIGHT RIGHT-JUSTIFIED + RIGHTPLUS RIGHTSPACE RISK RMC_COMMUNICATION_FAILURE + RMC_INVALID_STATUS RMC_SYSTEM_FAILURE ROLE ROLLBACK ROUND ROWS RPAD + RTRIM RUN SAP SAP-SPOOL SAVING SCALAR SCALE_PRESERVING + SCALE_PRESERVING_SCIENTIFIC SCAN SCIENTIFIC + SCIENTIFIC_WITH_LEADING_ZERO SCREEN SCROLL SCROLL-BOUNDARY SCROLLING + SEARCH SECONDARY SECONDS SECTION SELECT SELECT-OPTIONS SELECTION + SELECTION-SCREEN SELECTION-SET SELECTION-SETS SELECTION-TABLE + SELECTIONS SEND SEPARATE SEPARATED SET SHARED SHIFT SHORT + SHORTDUMP-ID SIGN SIGN_AS_POSTFIX SIMPLE SINGLE SIZE SKIP SKIPPING + SMART SOME SORT SORTABLE SORTED SOURCE SPACE SPECIFIED SPLIT SPOOL + SPOTS SQL SQLSCRIPT SSTRING STABLE STAMP STANDARD START-OF-SELECTION + STARTING STATE STATEMENT STATEMENTS STATIC STATICS STATUSINFO + STEP-LOOP STEP STOP STRING STRUCTURE STRUCTURES STYLE SUBKEY + SUBMATCHES SUBMIT SUBROUTINE SUBSCREEN SUBSTRING SUBTRACT + SUBTRACT-CORRESPONDING SUFFIX SUM SUMMARY SUMMING SUPPLIED SUPPLY + SUPPRESS SWITCH SWITCHSTATES SYMBOL SYNCPOINTS SYNTAX SYNTAX-CHECK + SYNTAX-TRACE SYST SYSTEM-CALL SYSTEM-EXCEPTIONS SYSTEM-EXIT TAB + TABBED TABLE TABLES TABLEVIEW TABSTRIP TARGET TASK TASKS TEST + TEST-INJECTION TEST-SEAM TESTING TEXT TEXTPOOL THEN THROW TIME TIMES + TIMESTAMP TIMEZONE TIMS TIMS_IS_VALID TITLE TITLE-LINES TITLEBAR TO + TOKENIZATION TOKENS TOP-LINES TOP-OF-PAGE TRACE-FILE TRACE-TABLE + TRAILING TRANSACTION TRANSFER TRANSFORMATION TRANSLATE TRANSPORTING + TRMAC TRUNCATE TRUNCATION TRY TSTMP_ADD_SECONDS + TSTMP_CURRENT_UTCTIMESTAMP TSTMP_IS_VALID TSTMP_SECONDS_BETWEEN TYPE + TYPE-POOL TYPE-POOLS TYPES ULINE UNASSIGN UNDER UNICODE UNION UNIQUE + UNIT UNIT_CONVERSION UNIX UNPACK UNTIL UNWIND UP UPDATE UPPER USER + USER-COMMAND USING UTF-8 VALID VALUE VALUE-REQUEST VALUES VARC VARY + VARYING VERIFICATION-MESSAGE VERSION VIA VIEW VISIBLE WAIT WARNING + WHEN WHENEVER WHERE WHILE WIDTH WINDOW WINDOWS WITH WITH-HEADING + WITH-TITLE WITHOUT WORD WORK WRITE WRITER XML XSD YELLOW YES YYMMDD + Z ZERO ZONE + ) + + BUILTINS = Set.new %w( + abs acos add_days add_months add_seconds apply asin assign atan + attribute bit-set boolc boolx call call-method cast ceil cfunc + charlen char_off class_constructor clear cluster cmax cmin cnt + coalesce communication_failure concat concat_lines_of cond cond-var + condense constructor contains contains_any_not_of contains_any_of + conv copy corresponding cos cosh count count_any_not_of count_any_of + create currency_conversion current_utctimestamp cursor data + days_between dbmaxlen dbtab deserialize destructor distance div + division empty error_message escape exact exp extensible filter find + find_any_not_of find_any_of find_end floor frac from_mixed group + hashed header idx include index insert ipow is_valid itab key lax let + lines line_exists line_index log log10 loop loop_key match matches me + mesh_path mod namespace new nmax nmin node numeric numofchar object + parameter primary_key read reduce ref repeat replace rescale + resource_failure reverse root round seconds_between segment sender + serialize shift_left shift_right sign simple sin sinh skip sorted + space sqrt standard strlen substring substring_after substring_before + substring_from substring_to sum switch switch-var system_failure + table table_line tan tanh template text to_lower to_mixed to_upper + transform translate trunc type unit_conversion value variable write + xsdbool xsequence xstrlen + ) + end + end +end diff --git a/lib/rouge/lexers/apache.rb b/lib/rouge/lexers/apache.rb index 57de58c11b..1e65858647 100644 --- a/lib/rouge/lexers/apache.rb +++ b/lib/rouge/lexers/apache.rb @@ -17,15 +17,11 @@ class Apache < RegexLexer end def name_for_token(token, tktype) - if SECTIONS.include? token - tktype - elsif DIRECTIVES.include? token - tktype - elsif VALUES.include? token - tktype - else - Text - end + return tktype if SECTIONS.include?(token) + return tktype if DIRECTIVES.include?(token) + return tktype if VALUES.include?(token) + + Text end state :whitespace do diff --git a/lib/rouge/lexers/viml.rb b/lib/rouge/lexers/viml.rb index 066e32dd03..55c7ff3cb7 100644 --- a/lib/rouge/lexers/viml.rb +++ b/lib/rouge/lexers/viml.rb @@ -49,11 +49,11 @@ class VimL < RegexLexer if KEYWORDS[:command].include? name token Keyword - elsif KEYWORDS[:function].include? name - token Name::Builtin - elsif KEYWORDS[:option].include? name - token Name::Builtin - elsif KEYWORDS[:auto].include? name + elsif ( + KEYWORDS[:function].include?(name) || + KEYWORDS[:option].include?(name) || + KEYWORDS[:auto].include?(name) + ) token Name::Builtin else token Text diff --git a/lib/rouge/lexers/yang.rb b/lib/rouge/lexers/yang.rb index a9d54f0663..71352c1c0c 100644 --- a/lib/rouge/lexers/yang.rb +++ b/lib/rouge/lexers/yang.rb @@ -13,74 +13,56 @@ class YANG < RegexLexer id = /[\w-]+(?=[^\w\-\:])\b/ #Keywords from RFC7950 ; oriented at BNF style - def self.top_stmts_keywords - @top_stms_keywords ||= Set.new %w( - module submodule - ) - end + top_keywords = Set.new %w(module submodule) - def self.module_header_stmts_keywords - @module_header_stmts_keywords ||= Set.new %w( - belongs-to namespace prefix yang-version - ) - end + module_header_keywords = Set.new %w(belongs-to namespace prefix yang-version) - def self.meta_stmts_keywords - @meta_stmts_keywords ||= Set.new %w( - contact description organization reference revision - ) - end + meta_keywords = Set.new %w(contact description organization reference revision) - def self.linkage_stmts_keywords - @linkage_stmts_keywords ||= Set.new %w( - import include revision-date - ) - end + linkage_keywords = Set.new %w(import include revision-date) - def self.body_stmts_keywords - @body_stms_keywords ||= Set.new %w( - action argument augment deviation extension feature grouping identity - if-feature input notification output rpc typedef - ) - end + body_keywords = Set.new %w( + action argument augment deviation extension feature grouping identity + if-feature input notification output rpc typedef + ) - def self.data_def_stmts_keywords - @data_def_stms_keywords ||= Set.new %w( - anydata anyxml case choice config container deviate leaf leaf-list - list must presence refine uses when - ) - end + data_def_keywords = Set.new %w( + anydata anyxml case choice config container deviate leaf leaf-list + list must presence refine uses when + ) - def self.type_stmts_keywords - @type_stmts_keywords ||= Set.new %w( - base bit default enum error-app-tag error-message fraction-digits - length max-elements min-elements modifier ordered-by path pattern - position range require-instance status type units value yin-element - ) - end + type_keywords = Set.new %w( + base bit default enum error-app-tag error-message fraction-digits + length max-elements min-elements modifier ordered-by path pattern + position range require-instance status type units value yin-element + ) - def self.list_stmts_keywords - @list_stmts_keywords ||= Set.new %w( - key mandatory unique - ) - end + list_keywords = Set.new %w( + key mandatory unique + ) #RFC7950 other keywords - def self.constants_keywords - @constants_keywords ||= Set.new %w( - add current delete deprecated false invert-match max min - not-supported obsolete replace true unbounded user - ) - end + CONSTANTS = Set.new %w( + add current delete deprecated false invert-match max min + not-supported obsolete replace true unbounded user + ) #RFC7950 Built-In Types - def self.types - @types ||= Set.new %w( - binary bits boolean decimal64 empty enumeration identityref - instance-identifier int16 int32 int64 int8 leafref string uint16 - uint32 uint64 uint8 union - ) - end + TYPES = Set.new %w( + binary bits boolean decimal64 empty enumeration identityref + instance-identifier int16 int32 int64 int8 leafref string uint16 + uint32 uint64 uint8 union + ) + + DECLARATIONS = + top_keywords + + module_header_keywords + + meta_keywords + + linkage_keywords + + body_keywords + + data_def_keywords + + type_keywords + + list_keywords state :comment do rule %r/[^*\/]/, Comment @@ -115,25 +97,11 @@ def self.types rule id do |m| name = m[0].downcase - if self.class.top_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.module_header_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.meta_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.linkage_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.body_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.data_def_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.type_stmts_keywords.include? name - token Keyword::Declaration - elsif self.class.list_stmts_keywords.include? name + if DECLARATIONS.include?(name) token Keyword::Declaration - elsif self.class.types.include? name + elsif TYPES.include? name token Keyword::Type - elsif self.class.constants_keywords.include? name + elsif CONSTANTS.include? name token Name::Constant else token Name diff --git a/lib/rouge/themes/gruvbox.rb b/lib/rouge/themes/gruvbox.rb index 8faf4cc5f6..7baebaca1f 100644 --- a/lib/rouge/themes/gruvbox.rb +++ b/lib/rouge/themes/gruvbox.rb @@ -10,6 +10,7 @@ module Themes class Gruvbox < CSSTheme name 'gruvbox' + # rubocop:disable Naming/ConstantName # global Gruvbox colours {{{ C_dark0_hard = '#1d2021' C_dark0 ='#282828' @@ -122,6 +123,8 @@ def self.make_light! palette orange: C_faded_orange end + # rubocop:enable Naming/ConstantName + dark! mode :light diff --git a/lib/rubocop/cop/rouge/no_huge_collections.rb b/lib/rubocop/cop/rouge/no_huge_collections.rb new file mode 100644 index 0000000000..26036ad3bb --- /dev/null +++ b/lib/rubocop/cop/rouge/no_huge_collections.rb @@ -0,0 +1,37 @@ +module RuboCop + module Cop + module Rouge + class NoHugeCollections < RuboCop::Cop::Base + MSG = 'Avoid collections of over 300 elements. ' \ + 'Place those in a lazy-loaded file, ideally ' \ + 'generated by a Rake task from the relevant documentation.' + + + def_node_matcher :set_literal?, <<~PATTERN + (send (const nil? :Set) :[] ...) + PATTERN + + RESTRICT_ON_SEND = [:[]] + MAX_SIZE = 300 + + Set["1", "2", "3"] + Set.new %w(1 2 3) + + def on_send(node) + return unless set_literal?(node) + + # adjust by 2 for the target and method name + if node.children.size - 2 > MAX_SIZE + add_offense(node) + end + end + + def on_array(node) + if node.children.size >= MAX_SIZE + add_offense(node) + end + end + end + end + end +end diff --git a/spec/formatters/html_spec.rb b/spec/formatters/html_spec.rb index af0266a747..f0d817d837 100644 --- a/spec/formatters/html_spec.rb +++ b/spec/formatters/html_spec.rb @@ -16,11 +16,11 @@ end describe '#inline_theme' do - class InlineTheme < Rouge::CSSTheme - style Name, :bold => true + inline_theme = Class.new(Rouge::CSSTheme) do + style self::Name, :bold => true end - let(:options) { { :inline_theme => InlineTheme.new, :wrap => false } } + let(:options) { { :inline_theme => inline_theme.new, :wrap => false } } let(:output) { subject.format([[Token['Name'], 'foo']]) diff --git a/spec/lexer_spec.rb b/spec/lexer_spec.rb index 8101d83946..5a358d067c 100644 --- a/spec/lexer_spec.rb +++ b/spec/lexer_spec.rb @@ -156,61 +156,61 @@ def incr end it 'delegates' do - class MasterLexer < Rouge::RegexLexer + braces_lexer = Class.new(Rouge::RegexLexer) do + state :root do + rule %r/b/, 'B' + end + end + + master_lexer = Class.new(Rouge::RegexLexer) do state :root do rule %r/a/, 'A' rule %r/{(.*?)}/ do |m| token 'brace', '{' - delegate BracesLexer.new, m[1] + delegate braces_lexer.new, m[1] token 'brace', '}' end end end - class BracesLexer < Rouge::RegexLexer - state :root do - rule %r/b/, 'B' - end - end - - assert_no_errors 'a{b}a', MasterLexer + assert_no_errors 'a{b}a', master_lexer end it 'detects the beginnings of lines with ^ rules' do - class MyLexer < Rouge::RegexLexer + my_lexer = Class.new(Rouge::RegexLexer) do state :root do rule %r/^a/, 'start' rule %r/a/, 'not-start' end end - assert_has_token('start', 'a', MyLexer) - assert_has_token('start', "\na", MyLexer) - deny_has_token('not-start', 'a', MyLexer) - assert_has_token('not-start', 'aa', MyLexer) + assert_has_token('start', 'a', my_lexer) + assert_has_token('start', "\na", my_lexer) + deny_has_token('not-start', 'a', my_lexer) + assert_has_token('not-start', 'aa', my_lexer) end it 'is undetectable by default' do - UndetectableLexer = Class.new(Rouge::Lexer) + undetectable_lexer = Class.new(Rouge::Lexer) - refute { UndetectableLexer.methods(false).include?(:detect?) } - refute { UndetectableLexer.detectable? } + refute { undetectable_lexer.methods(false).include?(:detect?) } + refute { undetectable_lexer.detectable? } end it 'can only be detectable within current scope' do - class DetectableLexer < Rouge::Lexer + detectable_lexer = Class.new(Rouge::Lexer) do def self.detect? text.shebang?('foobar') end end - assert { DetectableLexer.methods(false).include?(:detect?) } - assert { DetectableLexer.detectable? } + assert { detectable_lexer.methods(false).include?(:detect?) } + assert { detectable_lexer.detectable? } - NonDetectableLexer = Class.new(DetectableLexer) + non_detectable_lexer = Class.new(detectable_lexer) - refute { NonDetectableLexer.methods(false).include?(:detect?) } - refute { NonDetectableLexer.detectable? } + refute { non_detectable_lexer.methods(false).include?(:detect?) } + refute { non_detectable_lexer.detectable? } end it 'handles boolean options' do diff --git a/spec/lexers/terraform_spec.rb b/spec/lexers/terraform_spec.rb index 56f3ceedc6..f3a3c113a3 100644 --- a/spec/lexers/terraform_spec.rb +++ b/spec/lexers/terraform_spec.rb @@ -20,11 +20,5 @@ assert_guess :filename => 'foo.tofu' deny_guess :filename => 'foo' end - - it 'guesses by mimetype' do - end - - it 'guesses by source' do - end end end diff --git a/spec/theme_spec.rb b/spec/theme_spec.rb index d059cde82b..dfc231fb67 100644 --- a/spec/theme_spec.rb +++ b/spec/theme_spec.rb @@ -1,17 +1,17 @@ # -*- coding: utf-8 -*- # # frozen_string_literal: true +class TestTheme < Rouge::CSSTheme + style Literal::String, :fg => '#003366', :bold => true + style Literal::String::Backtick, :fg => '#555555', :italic => true +end + describe Rouge::Theme do def squish(str) str.strip.gsub(/\s+/, ' ') end - class MyTheme < Rouge::CSSTheme - style Literal::String, :fg => '#003366', :bold => true - style Literal::String::Backtick, :fg => '#555555', :italic => true - end - - let(:theme) { MyTheme.new } + let(:theme) { TestTheme.new } it 'auto-fills css classes' do rendered = theme.render diff --git a/spec/visual/samples/abap b/spec/visual/samples/abap index a99a7241f8..113fe1bd3d 100644 --- a/spec/visual/samples/abap +++ b/spec/visual/samples/abap @@ -1,4 +1,4 @@ --- ABAP Lexer +* Function module FUNCTION z_do_nothing. *"---------------------------------------------------------------------- @@ -24,20 +24,29 @@ FUNCTION z_do_nothing. FIELD-SYMBOLS: TYPE mara. -* some basic functions +* a full line comment + DATA(lv_int) = 1000. " just an initializer + + " create an object and call a method CREATE OBJECT lo_obj EXPORTING iv_int = lv_int. - lo_obj->do_nothing( ). - - SELECT SINGLE * FROM mara INTO ls_mara WHERE matkl EQ '1324'. + DATA(lv_result) = lo_obj->do_nothing( ). + DATA(lo_obj2) = new cl_any_class( lv_int ). -* some new functions from ABAP 7.40 - DATA(lv_int) = 1000. " just an initializer + " Get some material data + SELECT SINGLE matnr, matkl, mtart, maktx + FROM mara + INNER JOIN makt + ON makt~matnr EQ mara~matnr + INTO @ls_mara + WHERE matkl EQ '1324' + AND spras EQ @sy-langu. SELECT * FROM mara INTO TABLE @DATA(lt_mara). + " some ABAP 7.40 syntax LOOP AT lt_mara ASSIGNING FIELD-SYMBOL() GROUP BY ( carrid = -matkl count = GROUP SIZE ) ASCENDING @@ -71,4 +80,97 @@ FUNCTION z_do_nothing. " found ENDIF. + PERFORM do_something USING 'test' + CHANGING et_export. + ENDFUNCTION. + +* Form routine + +FORM do_something USING iv_input TYPE string + CHANGING ct_result TYPE icl_string_t. + + " some more code here ... + ct_result = VALUE #( + ( iv_input ) + ). + + APPEND iv_input + TO ct_result. + +ENDFORM. + +* CDS View + +@AbapCatalog.sqlViewName: 'ZBC_DTEL_SEARCHV' +@AbapCatalog.compiler.compareFilter: true +@AbapCatalog.preserveKey: true +@AccessControl.authorizationCheck: #CHECK +@EndUserText.label: 'Dataelement Search' + +define view ZBC_DTEL_SEARCH as select from dd04l + left outer join dd04t + on dd04t.rollname = dd04l.rollname + and dd04t.ddlanguage = $session.system_language +{ + key dd04l.rollname, + dd04l.domname, + dd04l.datatype, + dd04l.leng, + dd04l.decimals, + dd04l.lowercase, + dd04t.ddtext, + dd04t.reptext, + dd04t.scrtext_s, + dd04t.scrtext_m, + dd04t.scrtext_l +} + +* NEW operator +DATA(obj) = NEW class( ) + +* VALUE operator +itab = VALUE #( ) + +* CORRESPONDING operator +struct2 = CORRESPONDING #( struct1 ) + +* DEFINE VIEW ENTITY: all keywords +DEFINE VIEW ENTITY ZTest + +* keyword keyword name +ASSOCIATION TO ZEntity + +* keyword keyword name +COMPOSITION OF ZChild + +*** builtins *** +lv_result = conv( lv_value ) +div( arg1 arg2 ) +currency_conversion( ) +reduce( ) +filter( ) +corresponding( ) + +*** cond and switch *** +lv_result = COND #( WHEN lv_var = 1 THEN a ) +lv_result = SWITCH #( lv_var ) + +*** let *** +LET lv_var = 1 IN y +LOOP AT itab STEP 2 + +*** annotation should be a keyword*** +@ANNOTATION.label +MANY TO ONE + +*** name *** +$session.system_language + +* not a keyword * +dd04l.decimals +table.data + +*** not keywords *** +input = 'test' +output = 'result'