Commit b9e2d2dd authored by Jeffery To's avatar Jeffery To Committed by Christian Hergert

objj.lang: Fix/rewrite using updated JS highlighting

parent 9479563c
This diff is collapsed.
/**
* Built-in types
*/
@implementation SomeClass
{
id i;
BOOL i;
SEL i;
byte i;
char i;
short i;
int i;
long i;
float i;
double i;
signed i;
unsigned i;
signed char i;
unsigned long i;
unsigned long long i;
}
+ (void)fn
{
}
- (@action)fn
{
}
- (IBAction)fn
{
}
@end
/**
* Built-in values / functions
*/
// keywords
self;
super;
_cmd;
// values
YES;
NO;
nil;
Nil;
NULL;
// math constants
E;
LOG10E;
LOG2E;
LN10;
LN2;
PI;
PI2;
PI_2;
SQRT1_2;
SQRT2;
// math functions
ABS();
ACOS();
ASIN();
ATAN();
ATAN2();
CEIL();
COS();
EXP();
FLOOR();
LOG();
MAX();
MIN();
POW();
RAND();
ROUND();
SIN();
SQRT();
TAN();
// reference / dereference
var a, aRef = @ref(a);
@deref(aRef) = 5;
console.log(@deref(aRef));
// method reference
var a = @selector(setJobTitle:company:);
/**
* Literals
*/
// string
var a = @"foo";
var a = @'bar';
// array
var a = @[1, 2, 3];
// dictionary
var a = @{
@"border-color": "#000",
@"border-width": 1.0,
@"content-margin": CGSizeMakeZero(),
};
/**
* Messages
*/
[self length];
[self characterAtIndex:index];
[myPerson setJobTitle:"Founder" company:"Cappuccino Foundation"];
[[self alloc:42] initWithName:aName];
// no semicolon between message calls
[self length]
[obj arg:self]
[[obj arg:self] arg:@selector(foo:)];
/**
* Declarations
*/
/* Forward class declaration */
@class CPString
// Forward global variable declaration */
@global CPInvalidArgumentException
/* Class declaration */
@implementation Person : CPObject
{
CPString name;
// accessors
CPString name @accessors;
CPString _nickName @accessors(property=nickName);
BOOL _cool @accessors(getter=isCool, setter=setCool:);
id foo @accessors(readonly);
id bar @accessors(copy);
id baz @accessors(readwrite);
// outlet
@outlet CPButton button;
IBOutlet CPCheckBox checkbox;
}
// static method
+ (id)personWithName:(CPString)aName
{
return self;
}
// instance method
- (id)initWithName:(CPString)aName
{
self = [super init];
name = aName;
return self;
}
- (void)setName:(CPString)aName
{
name = aName;
}
- (CPString)name
{
return name;
}
@end
// categories
@implementation CPString (Reversing)
- (CPString)reverse
{
return reversedString;
}
@end
// adopting protocol
@implementation Person : CPObject <Move>
{
CPString name;
}
@end
/* Import */
@import <Foundation/CPObject.j>
@import "MyClass.j"
/* Protocol definition */
@protocol Move <CPObject>
@required
+ (void)walk;
@optional
- (void)run;
- (void)jump;
@end
/* Type definition */
@typedef CPButtonType
CPMomentaryLightButton = 0;
CPPushOnPushOffButton = 1;
CPToggleButton = 2;
/**
* Preprocessor directives
*/
#define foo 1
#undef foo
{
#ifdef foo
}
function () {
#ifndef foo
}
o = {
#if foo == 1
};
@implementation SomeClass
#elif defined(foo)
{
#else
id i;
}
#endif
+ (void)fn
#pragma \
mark foo
{
#include "foo.js"
}
@end
@protocol Move <CPObject>
#warning \
Warning \
message
@required
+ (void)walk;
@optional
- (void)run;
#error Error message
- (void)jump;
@end
// commented out
/*
#define foo 1
*/
// #define foo 1
// from file.js
/*
* Expressions (in expression statements)
*/
/*
* Literals
*/
/* Keyword values */
var NULL = null;
var TRUE = true;
var FALSE = false;
/* Number */
var decimal1 = 0;
var decimal2 = 123.45;
var decimal3 = .66667;
var decimal4 = 10e20;
var decimal5 = 0.2e+1;
var decimal6 = .5E-20;
var hex1 = 0xDEADBEEF;
var hex2 = 0Xcafebabe;
// ES2015 binary and octal numbers
let binary1 = 0b1010;
let binary2 = 0B00001111;
let octal1 = 0o0123;
let octal2 = 0O4567;
// Legacy octal numbers
var legacy_octal1 = 01;
var legacy_octal2 = 007;
// BigInt (ES2020)
var decimal1 = 0n;
var decimal2 = 123n;
var hex1 = 0xDEADBEEFn;
var hex2 = 0Xcafebaben;
var binary1 = 0b1010n;
var binary2 = 0B00001111n;
var octal1 = 0o0123n;
var octal2 = 0O4567n;
/* String */
// Escape sequences
'\b\f\n\r\t\v\0\'\"\\'; // Single character escape
"\1\01\001"; // Octal escape (Annex B)
'\xA9'; // Hexadecimal escape
"\u00a9"; // Unicode escape
'\u{1D306}'; // Unicode code point escape
/* Array literal */
[];
[1];
[1.0, 'two', 0x03];
// Trailing comma
[
[1,2,3],
[4,5,6],
];
// Spread syntax
[1, ...a, 2];
/* Object literal */
a = {};
a = { prop: 'value' };
a = { prop: 'value', extends: 1 };
// Trailing comma
a = {
prop: 'value',
extends: 1,
};
// Shorthand property names
a = { b, c, d };
// Getter / setter
a = {
_hidden: null,
get property() { return _hidden; },
set property(value) { this._hidden = value; }
};
// Shorthand function notation
a = {
method() {},
*generator() {},
// Async function (ES2017)
async method() {},
async /* comment */ method() {},
async() {},// method called "async"
async: false, // property called "async"
async prop: 'val', // incorrectly highlighted (syntax error)
// Async generator (ES2018)
async *generator() {}
};
// Computed property names
a = {
['prop']: 1,
['method']() {}
};
// Spread properties (ES2018)
a = { ...b };
/* Regular expression literal */
/abc/;
x = /abc/gi;
function_with_regex_arg(/abc/);
[ /abc/m, /def/u ];
a = { regex: /abc/s }; // s (dotAll): ES2018
(1 === 0) ? /abc/ : /def/;
/abc/; /* Comment */
/abc/; // Comment
var matches = /abc/.exec('Alphabet ... that should contain abc, right?');
// No regex here
a = [thing / thing, thing / thing];
x = a /b/ c / d;
// Character groups with backslashes
/[ab\\]/; // a, b or backslash
/[ab\]]/; // a, b or ]
/\\[ab]/; // a or b preceded by backslash
/\[ab]/; // Literally "[ab]"
// Control escape
/\cJ/;
// Unicode property escape (ES2018)
/\p{General_Category=Letter}/u;
/\p{Letter}/u;
// Named capture groups (ES2018)
/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
/(?<foobar>foo|bar)/u;
/^(?<half>.*).\k<half>$/u; // backreference
/* Template literal */
console.log(`The sum of 2 and 2 is ${2 + 2}`);
let y = 8;
let my_string = `This is a multiline
string that also contains
a template ${y + (4.1 - 2.2)}`;
/*
* Built-in values
*/
// global object values
Infinity;
NaN;
undefined;
// global object functions
decodeURIComponent();
decodeURI();
encodeURIComponent();
encodeURI();
eval();
isFinite();
isNaN();
parseFloat();
parseInt();
// constructors (subset)
Array();
BigInt(); // ES2020
Boolean();
Date();
Error();
Function();
Map();
Object();
Promise();
RegExp();
Set();
String();
Symbol();
// objects
JSON.parse();
Math.random();
// object keywords
arguments;
globalThis; // ES2020
new.target;
new . /* comment */ target;
super;
this;
new . /* comment
*/ target; // not correctly highlighted
new // comment
.target; // not correctly highlighted
// function keywords
import(); // ES2020
import /* comment */ (); // ES2020
import /* comment
*/ (); // not correctly highlighted (though it may appear correct)
import // comment
(); // not correctly highlighted (though it may appear correct)
// properties (subset)
array.length;
Math.PI;
Number.NaN;
object.constructor;
Class.prototype;
Symbol.asyncIterator; // ES2018
Symbol('desc').description; // ES2019
// methods (subset)
array.keys();
date.toString();
object.valueOf();
re.test();
array.includes(); // ES2016
Object.values(); // ES2017
Object.entries(); // ES2017
string.padStart(); // ES2017
string.padEnd(); // ES2017
Object.getOwnPropertyDescriptors(); // ES2017
promise.finally(); // ES2018
Object.fromEntries(); // ES2019
string.trimStart(); // ES2019
string.trimEnd(); // ES2019
array.flat(); // ES2019
array.flatMap(); // ES2019
string.matchAll(); // ES2020
Promise.allSettled(); // ES2020
BigInt.asUintN(); // ES2020
/*
* Function expression, arrow function
*/
a = function () { return 1 };
a = function fn() {
return;
};
a = function fn(x) {};
a = function fn(x, y) {};
// Arrow function
x => -x;
() => {};
(x, y) => x + y;
(x, y) => { return x + y; };
(x, y) => /* comment */ { return x + y; } /* comment */ ;
(x) => ({ a: x }); // return object
// Default parameters
a = function fn(x, y = 1) {};
(x, y = 1) => x + y;
// Parameter without default after default parameters
a = function fn(x = 1, y) {};
(x = 1, y) => x + y;
// Array destructuring
a = function fn([x]) {};
a = function fn([x, y]) {};
([x]) => x;
([x, y]) => x + y;
// Object destructuring
a = function fn({ x }) {};
a = function fn({ x, b: y }) {};
({ x }) => x;
({ x, b: y }) => x + y;
// Destructuring and default value
a = function f([x, y] = [1, 2], {c: z} = {c: 3}) {};
([x, y] = [1, 2], {c: z} = {c: x + y}) => x + y + z;
// Generator function
a = function*fn() {};
a = function * fn() {};
// Rest parameters
a = function fn(...rest) {};
a = function fn(x, y, ...rest) {};
(...rest) => rest;
(x, y, ...rest) => rest;
// Async function (ES2017)
a = async function fn() {};
a = async /* comment */ function fn() {};
a = async /* comment
*/ function fn() {}; // correctly highlighted, because async cannot be followed by a line terminator
async x => x;
async () => {};
async /* comment */ () => {};
async /* comment
*/ () => {}; // correctly highlighted, because async cannot be followed by a line terminator
async(); // incorrectly highlighted
// Async generator (ES2018)
a = async function * fn() {};
// Trailing comma (ES2017)
a = function fn(x, y,) {};
(x, y,) => x + y;
// Trailing comma after rest parameters (syntax error)
a = function fn(x, y, ...rest,) {};
(x, y, ...rest,) => rest;
/*
* Class expression
*/
a = class Foo {
constructor() {
}
method(x, y) {
return x + y;
}
*generator() {}
};
a = class extends Bar {
constructor() {
this._value = null;
}
get property() {
return this._value;
}
set property(x) {
this._value = x;
}
static get bar() {
return 'bar';
}
};
/*
* Operators
* use groupings to test, as there can only be one expression (in the
* first grouping item)
*/
// Grouping
( 1 + 2 );
// Increment / decrement
( ++a );
( --a );
( a++ );
( a-- );
// Keyword unary
( await promise() ); // ES2017
( delete obj.prop );
( new Array() );
( void 1 );
( typeof 'str' );
( yield 1 );
( yield* fn() );
// Arithmetic
( 1 + 2 );
( 1 - 2 );
( 1 * 2 );
( 1 / 2 );
( 1 % 2 );
( 1 ** 2 ); // ES2016
( +1 );
( -1 );
// Keyword relational
( prop in obj );
( obj instanceof constructor );
// Comparison
( 1 == 2 );
( 1 != 2 );
( 1 === 2 );
( 1 !== 2 );
( 1 < 2 );
( 1 > 2 );
( 1 <= 2 );
( 1 >= 2 );
// Bitwise
( 1 & 2 );
( 1 | 2 );
( 1 ^ 2 );
( ~1 );
( 1 << 2 );
( 1 >> 2 );
( 1 >>> 2 );
// Logical
( 1 && 2 );
( 1 || 2 );
( !1 );
// Assignment
( a = 1 );
( a += 1 );
( a -= 1 );
( a *= 1 );
( a /= 1 );
( a %= 1 );
( a **= 1 ); // ES2016
( a <<= 1 );
( a >>= 1