Skip to content

Commit 69108e1

Browse files
committed
JavaScript: # indicates a private class field or method
1 parent c06d333 commit 69108e1

File tree

7 files changed

+148
-15
lines changed

7 files changed

+148
-15
lines changed

Tmain/list-fields-with-prefix.d/stdout-expected.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ x UCTAGSxpath no NONE s-- no -- xpath for
3232
- UCTAGSpackage yes Go s-- no -- the real package specified by the package name
3333
- UCTAGSpackageName yes Go s-- no -- the name for referring the package
3434
- UCTAGSimplements yes Inko s-- no rw Trait being implemented
35+
- UCTAGSproperties no JavaScript s-- no -- properties (static)
3536
- UCTAGSassignment yes LdScript s-- no -- how a value is assigned to the symbol
3637
- UCTAGSdefiner yes Lisp s-- no -- the name of the function or macro that defines the unknown/Y-kind object
3738
- UCTAGSsectionMarker no Markdown s-- no -- character used for declaring section(#, ##, =, or -)

Tmain/list-fields.d/stdout-expected.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ z kind no NONE s-- no r- [tags output] prepend "kind:" to k/ (or K/) field outpu
5050
- package yes Go s-- no -- the real package specified by the package name
5151
- packageName yes Go s-- no -- the name for referring the package
5252
- implements yes Inko s-- no rw Trait being implemented
53+
- properties no JavaScript s-- no -- properties (static)
5354
- assignment yes LdScript s-- no -- how a value is assigned to the symbol
5455
- definer yes Lisp s-- no -- the name of the function or macro that defines the unknown/Y-kind object
5556
- sectionMarker no Markdown s-- no -- character used for declaring section(#, ##, =, or -)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
--fields=+a
2+
--fields-javascript=+{properties}
3+
--sort=no
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Class1 input.js /^class Class1$/;" c
2+
#value1 input.js /^ #value1$/;" M class:Class1 access:private
3+
#value2 input.js /^ static #value2$/;" M class:Class1 access:private properties:static
4+
method1 input.js /^ method1(arg1,arg2)$/;" m class:Class1
5+
#method2 input.js /^ #method2(arg1,arg2)$/;" m class:Class1 access:private
6+
Class2 input.js /^class Class2$/;" c
7+
#method3 input.js /^ static #method3(arg = 10)$/;" m class:Class2 access:private properties:static
8+
Class3 input.js /^var Class3 = class {$/;" c
9+
#method4 input.js /^ #method4(){}$/;" m class:Class3 access:private
10+
method5 input.js /^ static method5(){}$/;" m class:Class3 properties:static
11+
Class4 input.js /^var Class4 = class Class4_2 {$/;" c
12+
Class4_2 input.js /^var Class4 = class Class4_2 {$/;" c
13+
method6 input.js /^ method6(){}$/;" m class:Class4
14+
method7 input.js /^ static method7(){}$/;" m class:Class4 properties:static
15+
AnonymousClass1fa6c9a30101 input.js /^class {$/;" c
16+
method8 input.js /^ method8(n) { return n * n; }$/;" m class:AnonymousClass1fa6c9a30101
17+
func1 input.js /^function func1() {$/;" f
18+
InnerClass1 input.js /^ class InnerClass1 {$/;" c function:func1
19+
#method9 input.js /^ #method9() {$/;" m class:func1.InnerClass1 access:private
20+
InnerClass2 input.js /^ class InnerClass2 {$/;" c function:func1
21+
method10 input.js /^ method10() {$/;" m class:func1.InnerClass2
22+
Class5 input.js /^class Class5 {$/;" c
23+
method11 input.js /^ method11() {};$/;" m class:Class5
24+
#method12 input.js /^ #method12() {};$/;" m class:Class5 access:private
25+
func2 input.js /^function func2() {$/;" f
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
2+
class Class1
3+
{
4+
#value1
5+
static #value2
6+
7+
method1(arg1,arg2)
8+
{
9+
}
10+
11+
#method2(arg1,arg2)
12+
{
13+
}
14+
}
15+
16+
class Class2
17+
{
18+
static #method3(arg = 10)
19+
{
20+
}
21+
}
22+
23+
var Class3 = class {
24+
#method4(){}
25+
static method5(){}
26+
}
27+
28+
var Class4 = class Class4_2 {
29+
method6(){}
30+
static method7(){}
31+
}
32+
33+
class {
34+
method8(n) { return n * n; }
35+
}
36+
37+
function func1() {
38+
class InnerClass1 {
39+
#method9() {
40+
}
41+
}
42+
class InnerClass2 {
43+
method10() {
44+
}
45+
}
46+
}
47+
48+
class Class5 {
49+
method11() {};
50+
#method12() {};
51+
}
52+
53+
function func2() {
54+
}

docs/news/HEAD.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Incompatible changes
1414

1515
Parser related changes
1616
---------------------------------------------------------------------
17+
JavaScript:
18+
* A new field "properties" was added to indicate that a field or
19+
member of a class is static.
20+
* Class member names prefixed with # are recognized as private.
1721

1822
New parsers
1923
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

parsers/jscript.c

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ typedef enum eTokenType {
123123
TOKEN_REGEXP,
124124
TOKEN_POSTFIX_OPERATOR,
125125
TOKEN_STAR,
126+
TOKEN_HASH,
126127
/* To handle Babel's decorators.
127128
* Used only in readTokenFull or lower functions. */
128129
TOKEN_ATMARK,
@@ -144,6 +145,10 @@ typedef struct sTokenInfo {
144145
int c;
145146
} tokenInfo;
146147

148+
typedef enum {
149+
F_STATIC,
150+
} jsField;
151+
147152
/*
148153
* DATA DEFINITIONS
149154
*/
@@ -279,6 +284,14 @@ static kindDefinition JsKinds [] = {
279284
{ true, 'M', "field", "fields" },
280285
};
281286

287+
static fieldDefinition JsFields[] = {
288+
{
289+
.name = "properties",
290+
.description = "properties (static)",
291+
.enabled = true,
292+
},
293+
};
294+
282295
static const keywordTable JsKeywordTable [] = {
283296
/* keyword keyword ID */
284297
{ "function", KEYWORD_function },
@@ -487,7 +500,7 @@ static int makeJsRefTagsForNameChain (char *name_chain, const tokenInfo *token,
487500

488501
static int makeJsTagCommon (const tokenInfo *const token, const jsKind kind,
489502
vString *const signature, vString *const inheritance,
490-
bool anonymous, bool nulltag)
503+
bool anonymous, bool is_static, bool is_private, bool nulltag)
491504
{
492505
int index = CORK_NIL;
493506
const char *name = vStringValue (token->string);
@@ -526,6 +539,12 @@ static int makeJsTagCommon (const tokenInfo *const token, const jsKind kind,
526539
updateTagLine (&e, token->lineNumber, token->filePosition);
527540
e.extensionFields.scopeIndex = scope;
528541

542+
if (is_private)
543+
e.extensionFields.access = "private";
544+
545+
if (is_static)
546+
attachParserField (&e, JsFields[F_STATIC].ftype, "static");
547+
529548
#ifdef DO_TRACING
530549
{
531550
const char *scope_str = getNameStringForCorkIndex (scope);
@@ -573,19 +592,33 @@ static int makeJsTagCommon (const tokenInfo *const token, const jsKind kind,
573592
static int makeJsTag (const tokenInfo *const token, const jsKind kind,
574593
vString *const signature, vString *const inheritance)
575594
{
576-
return makeJsTagCommon (token, kind, signature, inheritance, false, false);
595+
return makeJsTagCommon (token, kind, signature, inheritance, false, false, false, false);
596+
}
597+
598+
static int makeJsTagMaybePrivate (const tokenInfo *const token, const jsKind kind,
599+
vString *const signature, vString *const inheritance,
600+
const bool is_static, const bool is_private)
601+
{
602+
if (is_private) {
603+
vString * s = vStringNewInit ("#");
604+
vStringCat (s, token->string);
605+
vStringCopy (token->string, s);
606+
vStringDelete (s);
607+
}
608+
609+
return makeJsTagCommon (token, kind, signature, inheritance, false, is_static, is_private, false);
577610
}
578611

579612
static int makeJsNullTag (const tokenInfo *const token, const jsKind kind,
580613
vString *const signature, vString *const inheritance)
581614
{
582-
return makeJsTagCommon (token, kind, signature, inheritance, false, true);
615+
return makeJsTagCommon (token, kind, signature, inheritance, false, false, false, true);
583616
}
584617

585618
static int makeClassTagCommon (tokenInfo *const token, vString *const signature,
586619
vString *const inheritance, bool anonymous)
587620
{
588-
return makeJsTagCommon (token, JSTAG_CLASS, signature, inheritance, anonymous, false);
621+
return makeJsTagCommon (token, JSTAG_CLASS, signature, inheritance, anonymous, false, false, false);
589622
}
590623

591624
static int makeClassTag (tokenInfo *const token, vString *const signature,
@@ -598,7 +631,7 @@ static int makeFunctionTagCommon (tokenInfo *const token, vString *const signatu
598631
bool generator, bool anonymous)
599632
{
600633
return makeJsTagCommon (token, generator ? JSTAG_GENERATOR : JSTAG_FUNCTION, signature, NULL,
601-
anonymous, false);
634+
anonymous, false, false, false);
602635
}
603636

604637
static int makeFunctionTag (tokenInfo *const token, vString *const signature, bool generator)
@@ -1300,11 +1333,11 @@ static void readTokenFullRaw (tokenInfo *const token, bool include_newlines, vSt
13001333
case '#':
13011334
/* skip shebang in case of e.g. Node.js scripts */
13021335
if (token->lineNumber > 1)
1303-
token->type = TOKEN_UNDEFINED;
1336+
token->type = TOKEN_HASH;
13041337
else if ((c = getcFromInputFile ()) != '!')
13051338
{
13061339
ungetcToInputFile (c);
1307-
token->type = TOKEN_UNDEFINED;
1340+
token->type = TOKEN_HASH;
13081341
}
13091342
else
13101343
{
@@ -1530,7 +1563,7 @@ static int parseMethodsInAnonymousObject (tokenInfo *const token)
15301563
anonGenerate (anon_object->string, "anonymousObject", JSTAG_VARIABLE);
15311564
anon_object->type = TOKEN_IDENTIFIER;
15321565

1533-
index = makeJsTagCommon (anon_object, JSTAG_VARIABLE, NULL, NULL, true, false);
1566+
index = makeJsTagCommon (anon_object, JSTAG_VARIABLE, NULL, NULL, true, false, false, false);
15341567
if (! parseMethods (token, index, false))
15351568
{
15361569
/* If no method is found, the anonymous object
@@ -2162,6 +2195,7 @@ static bool parseMethods (tokenInfo *const token, int class_index,
21622195
{
21632196
bool is_setter = false;
21642197
bool is_getter = false;
2198+
bool is_static = false;
21652199

21662200
if (!dont_read)
21672201
readToken (token);
@@ -2204,6 +2238,9 @@ static bool parseMethods (tokenInfo *const token, int class_index,
22042238
else if (isKeyword (saved_token, KEYWORD_async) ||
22052239
isKeyword (saved_token, KEYWORD_static))
22062240
{
2241+
if (isKeyword (saved_token, KEYWORD_static))
2242+
is_static = true;
2243+
22072244
/* can be a qualifier for another "keyword", so start over */
22082245
deleteToken (saved_token);
22092246
goto start;
@@ -2222,6 +2259,7 @@ static bool parseMethods (tokenInfo *const token, int class_index,
22222259
! isType (token, TOKEN_SEMICOLON))
22232260
{
22242261
bool is_generator = false;
2262+
bool is_private = false;
22252263
bool is_shorthand = false; /* ES6 shorthand syntax */
22262264
bool is_computed_name = false; /* ES6 computed property name */
22272265
bool is_dynamic_prop = false;
@@ -2235,6 +2273,11 @@ static bool parseMethods (tokenInfo *const token, int class_index,
22352273
is_generator = true;
22362274
readToken (token);
22372275
}
2276+
else if (isType (token, TOKEN_HASH))
2277+
{
2278+
is_private = true;
2279+
readToken (token);
2280+
}
22382281

22392282
if (isType (token, TOKEN_OPEN_SQUARE))
22402283
{
@@ -2352,7 +2395,7 @@ static bool parseMethods (tokenInfo *const token, int class_index,
23522395
else if (is_setter)
23532396
kind = JSTAG_SETTER;
23542397

2355-
index_for_name = makeJsTag (name, kind, signature, NULL);
2398+
index_for_name = makeJsTagMaybePrivate (name, kind, signature, NULL, is_static, is_private);
23562399
parseBlock (token, index_for_name);
23572400

23582401
/*
@@ -2448,7 +2491,7 @@ static bool parseMethods (tokenInfo *const token, int class_index,
24482491
else
24492492
{
24502493
bool is_property = isType (token, TOKEN_COMMA);
2451-
makeJsTag (name, is_property ? JSTAG_PROPERTY : JSTAG_FIELD, NULL, NULL);
2494+
makeJsTagMaybePrivate (name, is_property ? JSTAG_PROPERTY : JSTAG_FIELD, NULL, NULL, is_static, is_private);
24522495
if (!isType (token, TOKEN_SEMICOLON) && !is_property)
24532496
dont_read = true;
24542497
}
@@ -2517,7 +2560,7 @@ static bool parseES6Class (tokenInfo *const token, const tokenInfo *target_name)
25172560
TRACE_PRINT("Emitting tag for class '%s'", vStringValue(target_name->string));
25182561

25192562
int r = makeJsTagCommon (target_name, JSTAG_CLASS, NULL, inheritance,
2520-
(is_anonymous && (target_name == class_name)), false);
2563+
(is_anonymous && (target_name == class_name)), false, false, false);
25212564

25222565
if (! is_anonymous && target_name != class_name)
25232566
{
@@ -2855,7 +2898,7 @@ static bool parseStatementRHS (tokenInfo *const name, tokenInfo *const token, st
28552898
if ( parseMethods(token, p, false) )
28562899
{
28572900
jsKind kind = state->foundThis || strchr (vStringValue(name->string), '.') != NULL ? JSTAG_PROPERTY : JSTAG_VARIABLE;
2858-
state->indexForName = makeJsTagCommon (name, kind, NULL, NULL, anon_object, false);
2901+
state->indexForName = makeJsTagCommon (name, kind, NULL, NULL, anon_object, false, false, false);
28592902
moveChildren (p, state->indexForName);
28602903
}
28612904
else if ( token->nestLevel == 0 && state->isGlobal )
@@ -2902,7 +2945,7 @@ static bool parseStatementRHS (tokenInfo *const name, tokenInfo *const token, st
29022945
*/
29032946
if ( ( token->nestLevel == 0 && state->isGlobal ) || kind == JSTAG_PROPERTY )
29042947
{
2905-
state->indexForName = makeJsTagCommon (name, kind, NULL, NULL, false, false);
2948+
state->indexForName = makeJsTagCommon (name, kind, NULL, NULL, false, false, false, false);
29062949
}
29072950
}
29082951
else if (isKeyword (token, KEYWORD_new))
@@ -3762,6 +3805,8 @@ extern parserDefinition* JavaScriptParser (void)
37623805
*/
37633806
def->kindTable = JsKinds;
37643807
def->kindCount = ARRAY_SIZE (JsKinds);
3808+
def->fieldTable = JsFields;
3809+
def->fieldCount = ARRAY_SIZE (JsFields);
37653810
def->parser = findJsTags;
37663811
def->initialize = initialize;
37673812
def->finalize = finalize;
@@ -3773,8 +3818,8 @@ extern parserDefinition* JavaScriptParser (void)
37733818
def->dependencies = dependencies;
37743819
def->dependencyCount = ARRAY_SIZE (dependencies);
37753820

3776-
def->versionCurrent = 1;
3777-
def->versionAge = 1;
3821+
def->versionCurrent = 2;
3822+
def->versionAge = 2;
37783823

37793824
return def;
37803825
}

0 commit comments

Comments
 (0)