Skip to content

Commit

Permalink
@Class, @file, @sel support (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
iccir committed Oct 28, 2015
1 parent 9550000 commit d645561
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 3 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CHANGELOG

1.2.0
- Update to Esprima 2.7 (#38)
- Added @CLASS, @SEL, @FUNCTION for debugging (#58)
- Throw errors when the compiler will generate invalid code (#60)

1.1.1 - 1.1.4
Expand Down
49 changes: 46 additions & 3 deletions src/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -702,14 +702,54 @@ Generator.prototype.generate = function()
}
}

function handlePredefinedMacro(node)
{
var name = node.name;

if (name === "@CLASS") {
if (currentClass) {
modifier.select(node).replace('"' + currentClass.name + '"');
} else {
Utils.throwError(OJError.ParseError, 'Cannot use @CLASS outside of a class @implementation');
}

} else if (name === "@SEL") {
if (currentClass && currentMethodNode) {
modifier.select(node).replace('"' + currentMethodNode.selectorName + '"');
} else {
Utils.throwError(OJError.ParseError, 'Cannot use @SEL outside of a method definition');
}

} else if (name === "@FUNCTION") {
if (currentClass && currentMethodNode) {
modifier.select(node).replace('"' +
currentMethodNode.selectorType + "[" +
currentClass.name + " " +
currentMethodNode.selectorName + "]" +
'"');
} else {
Utils.throwError(OJError.ParseError, 'Cannot use @SEL outside of a method definition');
}

} else {
Utils.throwError(OJError.DollarOJIsReserved, 'Unknown identifier: "' + name + '"');
}
}

function handleIdentifier(node)
{
var name = node.name;

if (name.indexOf("$oj") == 0) {
if (name[3] == "$" || name[3] == "_") {
Utils.throwError(OJError.DollarOJIsReserved, "Identifiers may not start with \"$oj_\" or \"$oj$\"", node);
if (name[0] === "$") {
if (name.indexOf("$oj") == 0) {
if (name[3] == "$" || name[3] == "_") {
Utils.throwError(OJError.DollarOJIsReserved, "Identifiers may not start with \"$oj_\" or \"$oj$\"", node);
}
}

} else if (name[0] === "@") {
handlePredefinedMacro(node);
return;
}

if (currentMethodNode && currentClass && canBeInstanceVariableOrSelf(node)) {
Expand Down Expand Up @@ -1069,6 +1109,9 @@ Generator.prototype.generate = function()
} else if (type === Syntax.OJAtEachStatement) {
handleEachStatement(node);

} else if (type === Syntax.OJPredefinedMacro) {
handlePredefinedMacro(node);

} else if (type === Syntax.Literal) {
handleLiteral(node);

Expand Down
39 changes: 39 additions & 0 deletions test/issues/TestIssue58.oj
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
var assert = require("assert");

(function() { "use strict";

@implementation Issue58Class {
}

+ (BOOL) checkWithArgument:(BOOL)yn unused:(BOOL)yn2
{
assert.equal( @CLASS, "Issue58Class" );
assert.equal( @SEL, "checkWithArgument:unused:" );
assert.equal( @FUNCTION, "+[Issue58Class checkWithArgument:unused:]" );

return YES;
}

- (BOOL) check
{
assert.equal( @CLASS, "Issue58Class" );
assert.equal( @SEL, "check" );
assert.equal( @FUNCTION, "-[Issue58Class check]" );

return YES;
}


@end

}());



function runTests()
{
var instance = [[Issue58Class alloc] init];
return [instance check] && [[Issue58Class class] checkWithArgument:NO unused:NO];
}

runTests();

0 comments on commit d645561

Please sign in to comment.