Skip to content

Commit

Permalink
Merge pull request #2483 from masatake/ruby-improve-mixin-detection
Browse files Browse the repository at this point in the history
Ruby: improve mixin detection
  • Loading branch information
masatake authored Apr 3, 2020
2 parents 513872a + ea87271 commit 841a3bf
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 17 deletions.
4 changes: 4 additions & 0 deletions Units/parser-ruby.r/ruby-mixin-field.d/expected.tags
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@ E input.rb /^class E$/;" c mixin:extend:X,extend:Y,extend:Z
hi input.rb /^ def hi$/;" f class:E
F input.rb /^class F$/;" c mixin:extend:X
prep input.rb /^ def self.prep$/;" S class:F
G input.rb /^class G$/;" c mixin:include:X,prepend:Y,extend:Z
prep input.rb /^ def self.prep$/;" S class:G
H input.rb /^class H$/;" c mixin:include:X,prepend:Y,extend:Z
prep input.rb /^ def self.prep$/;" S class:H
24 changes: 24 additions & 0 deletions Units/parser-ruby.r/ruby-mixin-field.d/input.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,27 @@ def self.prep
extend X
end
end

class G
include(X)
def self.prep
prepend (Y)
end
extend ( Z)
end

class H
if true
unless false
include(X)
end
end
def self.prep
if true
unless false
prepend (Y)
end
end
end
extend ( Z)
end
16 changes: 6 additions & 10 deletions main/nestlevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,23 +100,19 @@ extern void nestingLevelsPop(NestingLevels *nls)
nls->n--;
}

extern NestingLevel *nestingLevelsGetCurrent(const NestingLevels *nls)
extern NestingLevel *nestingLevelsGetNthFromRoot (const NestingLevels *nls, int n)
{
Assert (nls != NULL);

if (nls->n < 1)
if (nls->n > n && n >= 0)
return NL_NTH(nls, n);
else
return NULL;

return NL_NTH(nls, (nls->n - 1));
}

extern NestingLevel *nestingLevelsGetNth(const NestingLevels *nls, int n)
extern NestingLevel *nestingLevelsGetNthParent (const NestingLevels *nls, int n)
{
Assert (nls != NULL);
if (nls->n > n && n >= 0)
return NL_NTH(nls, n);
else
return NULL;
return nestingLevelsGetNthFromRoot (nls, nls->n - 1 - n);
}

extern void *nestingLevelGetUserData (const NestingLevel *nl)
Expand Down
5 changes: 3 additions & 2 deletions main/nestlevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@ extern void nestingLevelsFree(NestingLevels *nls);
extern NestingLevel *nestingLevelsPush(NestingLevels *nls, int corkIndex);
extern NestingLevel * nestingLevelsTruncate(NestingLevels *nls, int depth, int corkIndex);
extern void nestingLevelsPop(NestingLevels *nls);
extern NestingLevel *nestingLevelsGetCurrent(const NestingLevels *nls);
extern NestingLevel *nestingLevelsGetNth(const NestingLevels *nls, int n);
#define nestingLevelsGetCurrent(NLS) nestingLevelsGetNthParent((NLS), 0)
extern NestingLevel *nestingLevelsGetNthFromRoot(const NestingLevels *nls, int n);
extern NestingLevel *nestingLevelsGetNthParent(const NestingLevels *nls, int n);

extern void *nestingLevelGetUserData (const NestingLevel *nl);

Expand Down
34 changes: 29 additions & 5 deletions parsers/ruby.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static vString* nestingLevelsToScope (const NestingLevels* nls)
vString* result = vStringNew ();
for (i = 0; i < nls->n; ++i)
{
NestingLevel *nl = nestingLevelsGetNth (nls, i);
NestingLevel *nl = nestingLevelsGetNthFromRoot (nls, i);
tagEntryInfo *e = getEntryOfNestingLevel (nl);
if (e && strlen (e->name) > 0 && (!e->placeholder))
{
Expand Down Expand Up @@ -462,22 +462,46 @@ static int readAndEmitTag (const unsigned char** cp, rubyKind expected_kind)
static void readAndStoreMixinSpec (const unsigned char** cp, const char *how_mixin)
{

NestingLevel *nl = nestingLevelsGetCurrent (nesting);
tagEntryInfo *e = getEntryOfNestingLevel (nl);
NestingLevel *nl = NULL;
tagEntryInfo *e = NULL;
int ownerLevel = 0;

for (ownerLevel = 0; ownerLevel < nesting->n; ownerLevel++)
{
nl = nestingLevelsGetNthParent (nesting, ownerLevel);
e = nl? getEntryOfNestingLevel (nl): NULL;

/* Ignore "if", "unless", "while" ... */
if ((nl && (nl->corkIndex == CORK_NIL)) || (e && e->placeholder))
continue;
break;
}

if (!e)
return;

if (e->kindIndex == K_SINGLETON)
{
nl = nestingLevelsGetNth (nesting, nesting->n - 2);
nl = nestingLevelsGetNthParent (nesting,
ownerLevel + 1);
if (nl == NULL)
return;
e = getEntryOfNestingLevel (nl);
}

if (!e)
return;

if (! (e->kindIndex == K_CLASS || e->kindIndex == K_MODULE))
return;

if (isspace (**cp))
if (isspace (**cp) || (**cp == '('))
{
if (isspace (**cp))
skipWhitespace (cp);
if (**cp == '(')
++*cp;

vString *spec = vStringNewInit (how_mixin);
vStringPut(spec, ':');

Expand Down

0 comments on commit 841a3bf

Please sign in to comment.