From 5cfe6117d07022625a04187099334bf957550469 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 7 Mar 2017 14:45:19 -0500 Subject: [PATCH 1/4] Initial rewrite of functions and function calls --- grammars/c.cson | 176 +++++++++++++++++++++++++++------------------ spec/c-spec.coffee | 95 ++++++++++++------------ 2 files changed, 156 insertions(+), 115 deletions(-) diff --git a/grammars/c.cson b/grammars/c.cson index 4d67412..f3844f8 100644 --- a/grammars/c.cson +++ b/grammars/c.cson @@ -22,9 +22,6 @@ 'match': '\\b(break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while)\\b' 'name': 'keyword.control.c' } - { - 'include': '#storage_types' - } { 'match': '\\b(const|extern|register|restrict|static|volatile|inline)\\b' 'name': 'storage.modifier.c' @@ -265,22 +262,41 @@ } { # FIRST CAPTURE meta.function.c scope (provides an injectable scope, balanced parentheses and prevents unnecessary scope nesting) + # TODO: Try to make this C-only 'begin': '''(?x) - (?!(?:while|for|do|if|else|switch|catch|enumerate|return|sizeof|[cr]?iterate|asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void)\\s*\\() (?= - (?:[A-Za-z_][A-Za-z0-9_]*+|::)++\\s*\\( # actual name - | - (?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\( + [A-Za-z_]\\w* # Type modifier + \\s+ + ( + ([A-Za-z_]\\w*+|::)++\\s*\\( # Actual name + | + ((?<=operator)([-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\( # Operator overloading (for C++) + ) ) ''' - 'end': '(?<=\\))(?!\\w)' + 'end': '(?<=})|(?=;)' 'name': 'meta.function.c' 'patterns': [ { - 'include': '#function-innards' + 'include': '#function-body' + } + { + 'begin': '\\G' + 'end': '(?<=\\))' + 'patterns': [ + { + 'include': '#function-innards' + } + ] } ] } + { + 'include': '#function-call' + } + { + 'include': '#storage_types' + } { 'include': '#line_continuation_character' } @@ -295,6 +311,21 @@ '4': 'name': 'variable.other.member.c' 'match': '((\\.)|(->))\\s*(([a-zA-Z_][a-zA-Z_0-9]*)\\b(?!\\s*\\())?' + 'arguments': + 'begin': '\\(' + 'beginCaptures': + '0': + 'name': 'punctuation.definition.arguments.begin.bracket.round.c' + 'end': '\\)' + 'endCaptures': + '0': + 'name': 'punctuation.definition.arguments.end.bracket.round.c' + 'name': 'meta.arguments.c' + 'patterns': [ + { + 'include': '$base' + } + ] 'block': 'patterns': [ { @@ -331,9 +362,6 @@ { 'include': '#libc' } - { - 'include': '#c_function_call' - } { 'captures': '1': @@ -379,21 +407,17 @@ 'include': '$base' } ] - 'c_function_call': + 'function-call': # FIRST CAPTURE meta.function-call.c scope (provides an injectable scope, balanced parentheses and prevents unnecessary scope nesting) - 'begin': '''(?x) - (?!(?:while|for|do|if|else|switch|catch|enumerate|return|sizeof|[cr]?iterate)\\s*\\() - (?= - (?:[A-Za-z_][A-Za-z0-9_]*+|::)++\\s*\\( # actual name - | - (?:(?<=operator)(?:[-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\( - ) - ''' - 'end': '(?<=\\))(?!\\w)' + 'begin': '([A-Za-z_]\\w*)(?=\\s*\\()' + 'beginCaptures': + '1': + 'name': 'entity.name.function.c' + 'end': '(?<=\\))' 'name': 'meta.function-call.c' 'patterns': [ { - 'include': '#function-call-innards' + 'include': '#arguments' } ] 'comments': @@ -510,6 +534,40 @@ 'name': 'constant.numeric.c' } ] + 'parameters': + 'patterns': [ + { + 'begin': '\\(' + 'beginCaptures': + '0': + 'name': 'punctuation.definition.parameters.begin.bracket.round.c' + 'end': '\\)' + 'endCaptures': + '0': + 'name': 'punctuation.definition.parameters.end.bracket.round.c' + 'name': 'meta.parameters.c' + 'patterns': [ + { + 'include': '#vararg_ellipses' + } + { + 'match': '\\b(const)\\b' + 'name': 'storage.modifier.c' + } + { + 'include': '#storage_types' + } + { + 'match': '[A-Za-z_]\\w*' + 'name': 'variable.parameter.c' + } + { + 'match': ',' + 'name': 'punctuation.separator.delimiter.c' + } + ] + } + ] 'parens': 'begin': '\\(' 'beginCaptures': @@ -613,10 +671,7 @@ 'include': '#libc' } { - 'include': '#c_function_call' - } - { - 'include': '$self' + 'include': '$base' } ] } @@ -713,6 +768,7 @@ } ] 'vararg_ellipses': + # TODO: Move to C++ 'match': '(?=+!]+|\\(\\)|\\[\\])) - ) - \\s*(\\() - ''' + 'begin': '{' 'beginCaptures': - '1': - 'name': 'entity.name.function.c' - '2': - 'name': 'punctuation.section.arguments.begin.bracket.round.c' - 'end': '\\)' + '0': + 'name': 'punctuation.definition.function.begin.bracket.curly.c' + 'end': '}' 'endCaptures': '0': - 'name': 'punctuation.section.arguments.end.bracket.round.c' + 'name': 'punctuation.definition.function.end.bracket.curly.c' + 'contentName': 'meta.function.body.c' 'patterns': [ { - 'include': '#function-innards' + 'include': '#block_innards' } ] } + ] + 'function-innards': + 'patterns': [ { - 'begin': '\\(' - 'beginCaptures': - '0': - 'name': 'punctuation.section.parens.begin.bracket.round.c' - 'end': '\\)' - 'endCaptures': - '0': - 'name': 'punctuation.section.parens.end.bracket.round.c' + 'include': '#comments' + } + { + 'match': '[A-Za-z_]\\w*(?=\\s*\\()' + 'name': 'entity.name.function.c' + } + { + 'include': '#parameters' + } + { + 'begin': '(?=[A-Za-z_]\\w*\\s+[A-Za-z_]\\w*\\s*\\()' + 'end': '(?=\\s+[A-Za-z_]\\w*\\s*\\()' + 'name': 'meta.function.return-type.c' 'patterns': [ { - 'include': '#function-innards' + 'include': '#storage_types' } ] } - { - 'include': '$base' - } ] 'function-call-innards': 'patterns': [ diff --git a/spec/c-spec.coffee b/spec/c-spec.coffee index d80d3cd..e6419b9 100644 --- a/spec/c-spec.coffee +++ b/spec/c-spec.coffee @@ -27,23 +27,24 @@ describe "Language-C", -> return 0; } ''' - expect(lines[0][0]).toEqual value: 'int', scopes: ['source.c', 'storage.type.c'] + expect(lines[0][0]).toEqual value: 'int', scopes: ['source.c', 'meta.function.c', 'meta.function.return-type.c', 'storage.type.c'] expect(lines[0][2]).toEqual value: 'something', scopes: ['source.c', 'meta.function.c', 'entity.name.function.c'] - expect(lines[0][3]).toEqual value: '(', scopes: ['source.c', 'meta.function.c', 'punctuation.section.arguments.begin.bracket.round.c'] - expect(lines[0][4]).toEqual value: 'int', scopes: ['source.c', 'meta.function.c', 'storage.type.c'] - expect(lines[0][6]).toEqual value: ')', scopes: ['source.c', 'meta.function.c', 'punctuation.section.arguments.end.bracket.round.c'] - expect(lines[0][8]).toEqual value: '{', scopes: ['source.c', 'meta.block.c', 'punctuation.section.block.begin.bracket.curly.c'] - expect(lines[1][1]).toEqual value: 'return', scopes: ['source.c', 'meta.block.c', 'keyword.control.c'] - expect(lines[1][3]).toEqual value: '0', scopes: ['source.c', 'meta.block.c', 'constant.numeric.c'] - expect(lines[2][0]).toEqual value: '}', scopes: ['source.c', 'meta.block.c', 'punctuation.section.block.end.bracket.curly.c'] + expect(lines[0][3]).toEqual value: '(', scopes: ['source.c', 'meta.function.c', 'meta.parameters.c', 'punctuation.definition.parameters.begin.bracket.round.c'] + expect(lines[0][4]).toEqual value: 'int', scopes: ['source.c', 'meta.function.c', 'meta.parameters.c', 'storage.type.c'] + expect(lines[0][6]).toEqual value: 'param', scopes: ['source.c', 'meta.function.c', 'meta.parameters.c', 'variable.parameter.c'] + expect(lines[0][7]).toEqual value: ')', scopes: ['source.c', 'meta.function.c', 'meta.parameters.c', 'punctuation.definition.parameters.end.bracket.round.c'] + expect(lines[0][9]).toEqual value: '{', scopes: ['source.c', 'meta.function.c', 'punctuation.definition.function.begin.bracket.curly.c'] + expect(lines[1][1]).toEqual value: 'return', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'keyword.control.c'] + expect(lines[1][3]).toEqual value: '0', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'constant.numeric.c'] + expect(lines[2][0]).toEqual value: '}', scopes: ['source.c', 'meta.function.c', 'punctuation.definition.function.end.bracket.curly.c'] it "tokenizes varargs ellipses", -> {tokens} = grammar.tokenizeLine 'void function(...);' - expect(tokens[0]).toEqual value: 'void', scopes: ['source.c', 'storage.type.c'] + expect(tokens[0]).toEqual value: 'void', scopes: ['source.c', 'meta.function.c', 'meta.function.return-type.c', 'storage.type.c'] expect(tokens[2]).toEqual value: 'function', scopes: ['source.c', 'meta.function.c', 'entity.name.function.c'] - expect(tokens[3]).toEqual value: '(', scopes: ['source.c', 'meta.function.c', 'punctuation.section.arguments.begin.bracket.round.c'] - expect(tokens[4]).toEqual value: '...', scopes: ['source.c', 'meta.function.c', 'punctuation.vararg-ellipses.c'] - expect(tokens[5]).toEqual value: ')', scopes: ['source.c', 'meta.function.c', 'punctuation.section.arguments.end.bracket.round.c'] + expect(tokens[3]).toEqual value: '(', scopes: ['source.c', 'meta.function.c', 'meta.parameters.c', 'punctuation.definition.parameters.begin.bracket.round.c'] + expect(tokens[4]).toEqual value: '...', scopes: ['source.c', 'meta.function.c', 'meta.parameters.c', 'punctuation.vararg-ellipses.c'] + expect(tokens[5]).toEqual value: ')', scopes: ['source.c', 'meta.function.c', 'meta.parameters.c', 'punctuation.definition.parameters.end.bracket.round.c'] it "tokenizes various _t types", -> {tokens} = grammar.tokenizeLine 'size_t var;' @@ -62,7 +63,7 @@ describe "Language-C", -> {tokens} = grammar.tokenizeLine 'ma' + '\\' + '\n' + 'in(){};' expect(tokens[0]).toEqual value: 'ma', scopes: ['source.c'] expect(tokens[1]).toEqual value: '\\', scopes: ['source.c', 'constant.character.escape.line-continuation.c'] - expect(tokens[3]).toEqual value: 'in', scopes: ['source.c', 'meta.function.c', 'entity.name.function.c'] + expect(tokens[3]).toEqual value: 'in', scopes: ['source.c', 'meta.function-call.c', 'entity.name.function.c'] # NOTE: Technically wrong, but a limitation of the line-based regex describe "numerics", -> it "recognizes numbers with digit separators", -> @@ -400,21 +401,21 @@ describe "Language-C", -> expect(lines[0][1]).toEqual value: 'if', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] expect(lines[0][3]).toEqual value: 'defined', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] expect(lines[0][5]).toEqual value: 'CREDIT', scopes: ['source.c', 'meta.preprocessor.c', 'entity.name.function.preprocessor.c'] - expect(lines[1][1]).toEqual value: 'credit', scopes: ['source.c', 'meta.function.c', 'entity.name.function.c'] - expect(lines[1][2]).toEqual value: '(', scopes: ['source.c', 'meta.function.c', 'punctuation.section.arguments.begin.bracket.round.c'] - expect(lines[1][3]).toEqual value: ')', scopes: ['source.c', 'meta.function.c', 'punctuation.section.arguments.end.bracket.round.c'] + expect(lines[1][1]).toEqual value: 'credit', scopes: ['source.c', 'meta.function-call.c', 'entity.name.function.c'] + expect(lines[1][2]).toEqual value: '(', scopes: ['source.c', 'meta.function-call.c', 'meta.arguments.c', 'punctuation.definition.arguments.begin.bracket.round.c'] + expect(lines[1][3]).toEqual value: ')', scopes: ['source.c', 'meta.function-call.c', 'meta.arguments.c', 'punctuation.definition.arguments.end.bracket.round.c'] expect(lines[2][0]).toEqual value: '#', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] expect(lines[2][1]).toEqual value: 'elif', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] expect(lines[2][3]).toEqual value: 'defined', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] expect(lines[2][5]).toEqual value: 'DEBIT', scopes: ['source.c', 'meta.preprocessor.c', 'entity.name.function.preprocessor.c'] - expect(lines[3][1]).toEqual value: 'debit', scopes: ['source.c', 'meta.function.c', 'entity.name.function.c'] - expect(lines[3][2]).toEqual value: '(', scopes: ['source.c', 'meta.function.c', 'punctuation.section.arguments.begin.bracket.round.c'] - expect(lines[3][3]).toEqual value: ')', scopes: ['source.c', 'meta.function.c', 'punctuation.section.arguments.end.bracket.round.c'] + expect(lines[3][1]).toEqual value: 'debit', scopes: ['source.c', 'meta.function-call.c', 'entity.name.function.c'] + expect(lines[3][2]).toEqual value: '(', scopes: ['source.c', 'meta.function-call.c', 'meta.arguments.c', 'punctuation.definition.arguments.begin.bracket.round.c'] + expect(lines[3][3]).toEqual value: ')', scopes: ['source.c', 'meta.function-call.c', 'meta.arguments.c', 'punctuation.definition.arguments.end.bracket.round.c'] expect(lines[4][0]).toEqual value: '#', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] expect(lines[4][1]).toEqual value: 'else', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] - expect(lines[5][1]).toEqual value: 'printerror', scopes: ['source.c', 'meta.function.c', 'entity.name.function.c'] - expect(lines[5][2]).toEqual value: '(', scopes: ['source.c', 'meta.function.c', 'punctuation.section.arguments.begin.bracket.round.c'] - expect(lines[5][3]).toEqual value: ')', scopes: ['source.c', 'meta.function.c', 'punctuation.section.arguments.end.bracket.round.c'] + expect(lines[5][1]).toEqual value: 'printerror', scopes: ['source.c', 'meta.function-call.c', 'entity.name.function.c'] + expect(lines[5][2]).toEqual value: '(', scopes: ['source.c', 'meta.function-call.c', 'meta.arguments.c', 'punctuation.definition.arguments.begin.bracket.round.c'] + expect(lines[5][3]).toEqual value: ')', scopes: ['source.c', 'meta.function-call.c', 'meta.arguments.c', 'punctuation.definition.arguments.end.bracket.round.c'] expect(lines[6][0]).toEqual value: '#', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] expect(lines[6][1]).toEqual value: 'endif', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] @@ -437,18 +438,18 @@ describe "Language-C", -> expect(lines[0][0]).toEqual value: '#', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] expect(lines[0][1]).toEqual value: 'if', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] expect(lines[0][3]).toEqual value: '1', scopes: ['source.c', 'meta.preprocessor.c', 'constant.numeric.c'] - expect(lines[1][0]).toEqual value: 'int', scopes: ['source.c', 'storage.type.c'] + expect(lines[1][0]).toEqual value: 'int', scopes: ['source.c', 'meta.function.c', 'meta.function.return-type.c', 'storage.type.c'] expect(lines[1][2]).toEqual value: 'something', scopes: ['source.c', 'meta.function.c', 'entity.name.function.c'] - expect(lines[2][1]).toEqual value: '#', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] - expect(lines[2][2]).toEqual value: 'if', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] - expect(lines[2][4]).toEqual value: '1', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'constant.numeric.c'] - expect(lines[3][1]).toEqual value: 'return', scopes: ['source.c', 'meta.block.c', 'keyword.control.c'] - expect(lines[3][3]).toEqual value: '1', scopes: ['source.c', 'meta.block.c', 'constant.numeric.c'] - expect(lines[4][1]).toEqual value: '#', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] - expect(lines[4][2]).toEqual value: 'else', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] - expect(lines[5][0]).toEqual value: ' return 0;', scopes: ['source.c', 'meta.block.c', 'comment.block.preprocessor.else-branch.in-block.c'] - expect(lines[6][1]).toEqual value: '#', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] - expect(lines[6][2]).toEqual value: 'endif', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] + expect(lines[2][1]).toEqual value: '#', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] + expect(lines[2][2]).toEqual value: 'if', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] + expect(lines[2][4]).toEqual value: '1', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'constant.numeric.c'] + expect(lines[3][1]).toEqual value: 'return', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'keyword.control.c'] + expect(lines[3][3]).toEqual value: '1', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'constant.numeric.c'] + expect(lines[4][1]).toEqual value: '#', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] + expect(lines[4][2]).toEqual value: 'else', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] + expect(lines[5][0]).toEqual value: ' return 0;', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'comment.block.preprocessor.else-branch.in-block.c'] + expect(lines[6][1]).toEqual value: '#', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] + expect(lines[6][2]).toEqual value: 'endif', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] expect(lines[8][0]).toEqual value: '#', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] expect(lines[8][1]).toEqual value: 'else', scopes: ['source.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] expect(lines[9][0]).toEqual value: 'int something() {', scopes: ['source.c', 'comment.block.preprocessor.else-branch.c'] @@ -465,18 +466,18 @@ describe "Language-C", -> #endif } ''' - expect(lines[0][0]).toEqual value: 'int', scopes: ['source.c', 'storage.type.c'] + expect(lines[0][0]).toEqual value: 'int', scopes: ['source.c', 'meta.function.c', 'meta.function.return-type.c', 'storage.type.c'] expect(lines[0][2]).toEqual value: 'something', scopes: ['source.c', 'meta.function.c', 'entity.name.function.c'] - expect(lines[1][1]).toEqual value: '#', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] - expect(lines[1][2]).toEqual value: 'if', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] - expect(lines[1][4]).toEqual value: '0', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'constant.numeric.c'] - expect(lines[2][0]).toEqual value: ' return 1;', scopes: ['source.c', 'meta.block.c', 'comment.block.preprocessor.if-branch.in-block.c'] - expect(lines[3][1]).toEqual value: '#', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] - expect(lines[3][2]).toEqual value: 'else', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] - expect(lines[4][1]).toEqual value: 'return', scopes: ['source.c', 'meta.block.c', 'keyword.control.c'] - expect(lines[4][3]).toEqual value: '0', scopes: ['source.c', 'meta.block.c', 'constant.numeric.c'] - expect(lines[5][1]).toEqual value: '#', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] - expect(lines[5][2]).toEqual value: 'endif', scopes: ['source.c', 'meta.block.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] + expect(lines[1][1]).toEqual value: '#', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] + expect(lines[1][2]).toEqual value: 'if', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] + expect(lines[1][4]).toEqual value: '0', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'constant.numeric.c'] + expect(lines[2][0]).toEqual value: ' return 1;', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'comment.block.preprocessor.if-branch.in-block.c'] + expect(lines[3][1]).toEqual value: '#', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] + expect(lines[3][2]).toEqual value: 'else', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] + expect(lines[4][1]).toEqual value: 'return', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'keyword.control.c'] + expect(lines[4][3]).toEqual value: '0', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'constant.numeric.c'] + expect(lines[5][1]).toEqual value: '#', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c', 'punctuation.definition.directive.c'] + expect(lines[5][2]).toEqual value: 'endif', scopes: ['source.c', 'meta.function.c', 'meta.function.body.c', 'meta.preprocessor.c', 'keyword.control.directive.conditional.c'] lines = grammar.tokenizeLines ''' #if 0 @@ -879,9 +880,9 @@ describe "Language-C", -> expect(tokens[1]).toEqual value: '?', scopes: ['source.c', 'keyword.operator.ternary.c'] expect(tokens[2]).toEqual value: ' ', scopes: ['source.c'] expect(tokens[3]).toEqual value: 'f', scopes: ['source.c', 'meta.function-call.c', 'entity.name.function.c'] - expect(tokens[4]).toEqual value: '(', scopes: ['source.c', 'meta.function-call.c', 'punctuation.section.arguments.begin.bracket.round.c'] - expect(tokens[5]).toEqual value: 'b', scopes: ['source.c', 'meta.function-call.c'] - expect(tokens[6]).toEqual value: ')', scopes: ['source.c', 'meta.function-call.c', 'punctuation.section.arguments.end.bracket.round.c'] + expect(tokens[4]).toEqual value: '(', scopes: ['source.c', 'meta.function-call.c', 'meta.arguments.c', 'punctuation.definition.arguments.begin.bracket.round.c'] + expect(tokens[5]).toEqual value: 'b', scopes: ['source.c', 'meta.function-call.c', 'meta.arguments.c'] + expect(tokens[6]).toEqual value: ')', scopes: ['source.c', 'meta.function-call.c', 'meta.arguments.c', 'punctuation.definition.arguments.end.bracket.round.c'] expect(tokens[7]).toEqual value: ' ', scopes: ['source.c'] expect(tokens[8]).toEqual value: ':', scopes: ['source.c', 'keyword.operator.ternary.c'] expect(tokens[9]).toEqual value: ' c', scopes: ['source.c'] From 779981cc9cff1f01bbd1e448d2e6e338f703d7fd Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 7 Mar 2017 15:23:09 -0500 Subject: [PATCH 2/4] Get return types in C++ working Wow we have literally no C++ spec coverage. --- grammars/c++.cson | 27 +++++++++++++--- grammars/c.cson | 79 +++++++++++++++++++++++------------------------ 2 files changed, 61 insertions(+), 45 deletions(-) diff --git a/grammars/c++.cson b/grammars/c++.cson index 2be5c5f..acf4196 100644 --- a/grammars/c++.cson +++ b/grammars/c++.cson @@ -20,6 +20,13 @@ ] 'firstLineMatch': '(?i)-\\*-[^*]*(Mode:\\s*)?C\\+\\+(\\s*;.*?)?\\s*-\\*-' 'name': 'C++' +'injections': + 'L:source.cpp meta.function.c meta.function.return-type.c': + 'patterns': [ + { + 'include': '#storage_types' + } + ] 'patterns': [ { 'include': '#special_block' @@ -65,15 +72,15 @@ 'name': 'keyword.operator.cast.cpp' } { - 'match': '\\b(and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\b' - 'name': 'keyword.operator.cpp' + 'match': '\\bdecltype\\b' + 'name': 'keyword.operator.decltype.cpp' } { - 'match': '\\b(class|decltype|wchar_t|char16_t|char32_t)\\b' - 'name': 'storage.type.cpp' + 'match': '\\b(and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eq|alignof|alignas)\\b' + 'name': 'keyword.operator.cpp' } { - 'match': '\\b(constexpr|export|mutable|typename|thread_local)\\b' + 'match': '\\b(class|constexpr|export|mutable|typename|thread_local)\\b' 'name': 'storage.modifier.cpp' } { @@ -129,6 +136,9 @@ { 'include': 'source.c' } + { + 'include': '#storage_types' + } ] 'repository': 'angle_brackets': @@ -364,6 +374,13 @@ ] } ] + 'storage_types': + 'patterns': [ + { + 'match': '\\b(wchar_t|char16_t|char32_t)\\b' + 'name': 'storage.type.cpp' + } + ] 'strings': 'patterns': [ { diff --git a/grammars/c.cson b/grammars/c.cson index f3844f8..5033821 100644 --- a/grammars/c.cson +++ b/grammars/c.cson @@ -215,45 +215,6 @@ } ] } - { - 'match': '\\b(u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|div_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t)\\b' - 'name': 'support.type.sys-types.c' - } - { - 'match': '\\b(pthread_attr_t|pthread_cond_t|pthread_condattr_t|pthread_mutex_t|pthread_mutexattr_t|pthread_once_t|pthread_rwlock_t|pthread_rwlockattr_t|pthread_t|pthread_key_t)\\b' - 'name': 'support.type.pthread.c' - } - { - 'match': '''(?x) \\b - (int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t - |int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t - |uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t - |uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t - |uintmax_t|uintmax_t) - \\b''' - 'name': 'support.type.stdint.c' - } - { - 'match': '\\b(noErr|kNilOptions|kInvalidID|kVariableLengthArray)\\b' - 'name': 'support.constant.mac-classic.c' - } - { - 'match': '''(?x) \\b - (AbsoluteTime|Boolean|Byte|ByteCount|ByteOffset|BytePtr|CompTimeValue|ConstLogicalAddress|ConstStrFileNameParam - |ConstStringPtr|Duration|Fixed|FixedPtr|Float32|Float32Point|Float64|Float80|Float96|FourCharCode|Fract|FractPtr - |Handle|ItemCount|LogicalAddress|OptionBits|OSErr|OSStatus|OSType|OSTypePtr|PhysicalAddress|ProcessSerialNumber - |ProcessSerialNumberPtr|ProcHandle|Ptr|ResType|ResTypePtr|ShortFixed|ShortFixedPtr|SignedByte|SInt16|SInt32|SInt64 - |SInt8|Size|StrFileName|StringHandle|StringPtr|TimeBase|TimeRecord|TimeScale|TimeValue|TimeValue64|UInt16|UInt32 - |UInt64|UInt8|UniChar|UniCharCount|UniCharCountPtr|UniCharPtr|UnicodeScalarValue|UniversalProcHandle|UniversalProcPtr - |UnsignedFixed|UnsignedFixedPtr|UnsignedWide|UTF16Char|UTF32Char|UTF8Char) - \\b''' - 'name': 'support.type.mac-classic.c' - } - { - # Reserved POSIX types - 'match': '\\b([A-Za-z0-9_]+_t)\\b' - 'name': 'support.type.posix-reserved.c' - } { 'include': '#block' } @@ -294,6 +255,45 @@ { 'include': '#function-call' } + { + 'match': '\\b(u_char|u_short|u_int|u_long|ushort|uint|u_quad_t|quad_t|qaddr_t|caddr_t|daddr_t|div_t|dev_t|fixpt_t|blkcnt_t|blksize_t|gid_t|in_addr_t|in_port_t|ino_t|key_t|mode_t|nlink_t|id_t|pid_t|off_t|segsz_t|swblk_t|uid_t|id_t|clock_t|size_t|ssize_t|time_t|useconds_t|suseconds_t)\\b' + 'name': 'support.type.sys-types.c' + } + { + 'match': '\\b(pthread_attr_t|pthread_cond_t|pthread_condattr_t|pthread_mutex_t|pthread_mutexattr_t|pthread_once_t|pthread_rwlock_t|pthread_rwlockattr_t|pthread_t|pthread_key_t)\\b' + 'name': 'support.type.pthread.c' + } + { + 'match': '''(?x) \\b + (int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|int_least8_t + |int_least16_t|int_least32_t|int_least64_t|uint_least8_t|uint_least16_t|uint_least32_t + |uint_least64_t|int_fast8_t|int_fast16_t|int_fast32_t|int_fast64_t|uint_fast8_t + |uint_fast16_t|uint_fast32_t|uint_fast64_t|intptr_t|uintptr_t|intmax_t|intmax_t + |uintmax_t|uintmax_t) + \\b''' + 'name': 'support.type.stdint.c' + } + { + 'match': '\\b(noErr|kNilOptions|kInvalidID|kVariableLengthArray)\\b' + 'name': 'support.constant.mac-classic.c' + } + { + 'match': '''(?x) \\b + (AbsoluteTime|Boolean|Byte|ByteCount|ByteOffset|BytePtr|CompTimeValue|ConstLogicalAddress|ConstStrFileNameParam + |ConstStringPtr|Duration|Fixed|FixedPtr|Float32|Float32Point|Float64|Float80|Float96|FourCharCode|Fract|FractPtr + |Handle|ItemCount|LogicalAddress|OptionBits|OSErr|OSStatus|OSType|OSTypePtr|PhysicalAddress|ProcessSerialNumber + |ProcessSerialNumberPtr|ProcHandle|Ptr|ResType|ResTypePtr|ShortFixed|ShortFixedPtr|SignedByte|SInt16|SInt32|SInt64 + |SInt8|Size|StrFileName|StringHandle|StringPtr|TimeBase|TimeRecord|TimeScale|TimeValue|TimeValue64|UInt16|UInt32 + |UInt64|UInt8|UniChar|UniCharCount|UniCharCountPtr|UniCharPtr|UnicodeScalarValue|UniversalProcHandle|UniversalProcPtr + |UnsignedFixed|UnsignedFixedPtr|UnsignedWide|UTF16Char|UTF32Char|UTF8Char) + \\b''' + 'name': 'support.type.mac-classic.c' + } + { + # Reserved POSIX types + 'match': '\\b([A-Za-z0-9_]+_t)\\b' + 'name': 'support.type.posix-reserved.c' + } { 'include': '#storage_types' } @@ -768,7 +768,6 @@ } ] 'vararg_ellipses': - # TODO: Move to C++ 'match': '(? Date: Tue, 7 Mar 2017 16:06:36 -0500 Subject: [PATCH 3/4] Operator overloading --- grammars/c++.cson | 24 ++++++++++++++++++++++++ grammars/c.cson | 12 ++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/grammars/c++.cson b/grammars/c++.cson index acf4196..df59e21 100644 --- a/grammars/c++.cson +++ b/grammars/c++.cson @@ -27,6 +27,27 @@ 'include': '#storage_types' } ] + 'source.cpp meta.function.c - meta.function.body.c': + 'patterns': [ + { + 'match': '(operator([-*&<>=+!]+|\\(\\)|\\[\\]))(?=\\s*\\()' + 'captures': + '1': + 'name': 'entity.name.function.cpp' + '2': + 'name': 'keyword.operator.c' + } + { + 'begin': '(?=[A-Za-z_]\\w*\\s+(operator([-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\()' + 'end': '(?!\\G)' + 'name': 'meta.function.return-type.c' + 'patterns': [ + { + 'include': '#storage_types' + } + ] + } + ] 'patterns': [ { 'include': '#special_block' @@ -380,6 +401,9 @@ 'match': '\\b(wchar_t|char16_t|char32_t)\\b' 'name': 'storage.type.cpp' } + { + 'include': 'source.c#storage_types' + } ] 'strings': 'patterns': [ diff --git a/grammars/c.cson b/grammars/c.cson index 5033821..60af6aa 100644 --- a/grammars/c.cson +++ b/grammars/c.cson @@ -226,13 +226,14 @@ # TODO: Try to make this C-only 'begin': '''(?x) (?= - [A-Za-z_]\\w* # Type modifier + [A-Za-z_]\\w* # Type modifier \\s+ ( - ([A-Za-z_]\\w*+|::)++\\s*\\( # Actual name + ([A-Za-z_]\\w*+|::)++ # Actual name | - ((?<=operator)([-*&<>=+!]+|\\(\\)|\\[\\]))\\s*\\( # Operator overloading (for C++) + (operator([-*&<>=+!]+|\\(\\)|\\[\\])) # Operator overloading (for C++) ) + \\s*\\( ) ''' 'end': '(?<=})|(?=;)' @@ -250,6 +251,9 @@ } ] } + { + 'include': '#comments' + } ] } { @@ -1751,7 +1755,7 @@ } { 'begin': '(?=[A-Za-z_]\\w*\\s+[A-Za-z_]\\w*\\s*\\()' - 'end': '(?=\\s+[A-Za-z_]\\w*\\s*\\()' + 'end': '(?!\\G)' 'name': 'meta.function.return-type.c' 'patterns': [ { From 7bec2cd555cad78b874352f9735d27faf8dd0bbd Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 7 Mar 2017 16:09:06 -0500 Subject: [PATCH 4/4] L: not required --- grammars/c++.cson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grammars/c++.cson b/grammars/c++.cson index df59e21..4193526 100644 --- a/grammars/c++.cson +++ b/grammars/c++.cson @@ -21,7 +21,7 @@ 'firstLineMatch': '(?i)-\\*-[^*]*(Mode:\\s*)?C\\+\\+(\\s*;.*?)?\\s*-\\*-' 'name': 'C++' 'injections': - 'L:source.cpp meta.function.c meta.function.return-type.c': + 'source.cpp meta.function.c meta.function.return-type.c': 'patterns': [ { 'include': '#storage_types'