mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 21:17:03 +00:00
New: dictionary literals in Objective-J 2.0.
This commit is contained in:
@@ -774,6 +774,35 @@ Identifier: function(node, st, c) {
|
||||
}
|
||||
}
|
||||
},
|
||||
DictionaryLiteral: function(node, st, c) {
|
||||
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.start));
|
||||
st.compiler.lastPos = node.start;
|
||||
|
||||
if (!node.keys.length) {
|
||||
CONCAT(st.compiler.jsBuffer, "objj_msgSend(objj_msgSend(CPDictionary, \"alloc\"), \"init\")");
|
||||
} else {
|
||||
CONCAT(st.compiler.jsBuffer, "objj_msgSend(objj_msgSend(CPDictionary, \"alloc\"), \"initWithObjectsAndKeys:\"");
|
||||
for (var i = 0; i < node.keys.length; i++) {
|
||||
var key = node.keys[i],
|
||||
value = node.values[i];
|
||||
|
||||
CONCAT(st.compiler.jsBuffer, ", ");
|
||||
|
||||
st.compiler.lastPos = value.start;
|
||||
c(value, st, "Expression");
|
||||
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, value.end));
|
||||
|
||||
CONCAT(st.compiler.jsBuffer, ", ");
|
||||
|
||||
st.compiler.lastPos = key.start;
|
||||
c(key, st, "Expression");
|
||||
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, key.end));
|
||||
}
|
||||
CONCAT(st.compiler.jsBuffer, ")");
|
||||
}
|
||||
|
||||
st.compiler.lastPos = node.end;
|
||||
},
|
||||
SelectorLiteralExpression: function(node, st, c) {
|
||||
CONCAT(st.compiler.jsBuffer, st.compiler.source.substring(st.compiler.lastPos, node.start));
|
||||
CONCAT(st.compiler.jsBuffer, "sel_getUid(\"");
|
||||
|
||||
@@ -273,6 +273,7 @@ if (!exports.acorn) {
|
||||
var _implementation = {keyword: "implementation"}, _outlet = {keyword: "outlet"}, _accessors = {keyword: "accessors"};
|
||||
var _end = {keyword: "end"}, _import = {keyword: "import", afterImport: true};
|
||||
var _action = {keyword: "action"}, _selector = {keyword: "selector"}, _class = {keyword: "class"}, _global = {keyword: "global"};
|
||||
var _dictionaryLiteral = {keyword: "{"};
|
||||
|
||||
// Objective-J keywords
|
||||
|
||||
@@ -660,6 +661,9 @@ if (!exports.acorn) {
|
||||
var next = input.charCodeAt(++tokPos);
|
||||
if (next === 34 || next === 39) // Read string if "'" or '"'
|
||||
return readString(next);
|
||||
if (next === 123) // Read dictionary literal if "{"
|
||||
return finishToken(_dictionaryLiteral);
|
||||
|
||||
var word = readWord1(),
|
||||
token = objJAtKeywordTypes[word];
|
||||
if (!token) raise(tokStart, "Unrecognized Objective-J keyword '@" + word + "'");
|
||||
@@ -1878,6 +1882,15 @@ if (!exports.acorn) {
|
||||
node.elements = parseExprList(_bracketR, firstExpr, true, true);
|
||||
return finishNode(node, "ArrayExpression");
|
||||
|
||||
case _dictionaryLiteral:
|
||||
var node = startNode();
|
||||
next();
|
||||
|
||||
var r = parseDictionary();
|
||||
node.keys = r[0];
|
||||
node.values = r[1];
|
||||
return finishNode(node, "DictionaryLiteral");
|
||||
|
||||
case _braceL:
|
||||
return parseObj();
|
||||
|
||||
@@ -2088,6 +2101,26 @@ if (!exports.acorn) {
|
||||
return elts;
|
||||
}
|
||||
|
||||
// Parses a comma-separated list of <key>:<value> pairs and returns them as
|
||||
// [arrayOfKeyExpressions, arrayOfValueExpressions].
|
||||
function parseDictionary() {
|
||||
expect(_braceL, "Expected '{' before dictionary");
|
||||
|
||||
var keys = [], values = [], first = true;
|
||||
while (!eat(_braceR)) {
|
||||
if (!first) {
|
||||
expect(_comma, "Expected ',' between expressions");
|
||||
if (options.allowTrailingCommas && eat(_braceR)) break;
|
||||
}
|
||||
|
||||
keys.push(parseExpression(true, true));
|
||||
expect(_colon, "Expected ':' between dictionary key and value");
|
||||
values.push(parseExpression(true, true));
|
||||
first = false;
|
||||
}
|
||||
return [keys, values];
|
||||
}
|
||||
|
||||
// Parse the next token as an identifier. If `liberal` is true (used
|
||||
// when parsing properties), it will also convert keywords into
|
||||
// identifiers.
|
||||
|
||||
@@ -155,6 +155,14 @@ if (!exports.acorn) {
|
||||
if (elt) c(elt, st, "Expression");
|
||||
}
|
||||
};
|
||||
exports.DictionaryLiteral = function(node, st, c) {
|
||||
for (var i = 0; i < node.keys.length; i++) {
|
||||
var key = node.keys[i];
|
||||
c(key, st, "Expression");
|
||||
var value = node.values[i];
|
||||
c(value, st, "Expression");
|
||||
}
|
||||
};
|
||||
exports.ObjectExpression = function(node, st, c) {
|
||||
for (var i = 0; i < node.properties.length; ++i)
|
||||
c(node.properties[i].value, st, "Expression");
|
||||
@@ -195,7 +203,7 @@ if (!exports.acorn) {
|
||||
c(node.body[i], st, "Statement");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
exports.ImportStatement = ignore;
|
||||
|
||||
exports.IvarDeclaration = ignore;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
@import <Foundation/CPDictionary.j>
|
||||
|
||||
@import <OJUnit/OJTestCase.j>
|
||||
|
||||
@implementation CPDictionaryTest : OJTestCase
|
||||
{
|
||||
CPDictionary string_dict;
|
||||
@@ -403,9 +405,40 @@
|
||||
{
|
||||
var dict = [[CPDictionary alloc] initWithObjectsAndKeys:@"Value1", @"Key1", nil, @"Key2", @"Value3", @"Key3"];
|
||||
|
||||
[self assert:2 equals:[dict count]];
|
||||
[self assert:2 equals:[dict count]];
|
||||
[self assert:@"Value1" equals:[dict objectForKey:@"Key1"]];
|
||||
[self assert:nil equals:[dict objectForKey:@"Key2"]]; // No key/value pair
|
||||
[self assert:@"Value3" equals:[dict objectForKey:@"Key3"]];
|
||||
}
|
||||
|
||||
- (void)testDictionaryLiteral
|
||||
{
|
||||
var dict = @{
|
||||
@"Key1": @"Value1",
|
||||
@"Key2": [CPNull null],
|
||||
@"Key3": 2
|
||||
};
|
||||
|
||||
[self assert:3 equals:[dict count]];
|
||||
[self assert:@"Value1" equals:[dict objectForKey:@"Key1"]];
|
||||
[self assert:[CPNull null] same:[dict objectForKey:@"Key2"]];
|
||||
[self assert:2 equals:[dict objectForKey:@"Key3"]];
|
||||
}
|
||||
|
||||
- (void)testDictionaryLiteralExpressions
|
||||
{
|
||||
var aKey = @"aKey",
|
||||
aValue = 5,
|
||||
dict = @{
|
||||
@"Key" + 1: @"Value" + 1,
|
||||
@"Key2": NO ? 1 : 2,
|
||||
aKey: aValue, // trailing comma is allowed
|
||||
};
|
||||
|
||||
[self assert:3 equals:[dict count]];
|
||||
[self assert:@"Value1" equals:[dict objectForKey:@"Key1"]];
|
||||
[self assert:2 equals:[dict objectForKey:@"Key2"]];
|
||||
[self assert:5 equals:[dict objectForKey:@"aKey"]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
{
|
||||
var dict = new CFMutableDictionary();
|
||||
[self assert:0 equals:dict.countOfValue(@"123")];
|
||||
|
||||
|
||||
dict.setValueForKey(@"abc", @"123");
|
||||
[self assert:1 equals:dict.countOfValue(@"123")];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user