mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 15:12:12 +00:00
Add @operator.binary
, @operator.prefix
, @operator.postfix
decorators for #124
This commit is contained in:
parent
9d25f78fc1
commit
f69bccfe09
2
dist/asc.js
vendored
2
dist/asc.js
vendored
File diff suppressed because one or more lines are too long
2
dist/asc.js.map
vendored
2
dist/asc.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js
vendored
2
dist/assemblyscript.js
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js.map
vendored
2
dist/assemblyscript.js.map
vendored
File diff suppressed because one or more lines are too long
83
src/ast.ts
83
src/ast.ts
@ -191,17 +191,15 @@ export abstract class Node {
|
|||||||
// special
|
// special
|
||||||
|
|
||||||
static createDecorator(
|
static createDecorator(
|
||||||
expression: Expression,
|
name: Expression,
|
||||||
args: Expression[] | null,
|
args: Expression[] | null,
|
||||||
range: Range
|
range: Range
|
||||||
): DecoratorNode {
|
): DecoratorNode {
|
||||||
var stmt = new DecoratorNode();
|
var stmt = new DecoratorNode();
|
||||||
stmt.range = range;
|
stmt.range = range;
|
||||||
stmt.name = expression; expression.parent = stmt;
|
stmt.name = name; name.parent = stmt;
|
||||||
stmt.arguments = args; if (args) setParent(args, stmt);
|
stmt.arguments = args; if (args) setParent(args, stmt);
|
||||||
stmt.decoratorKind = expression.kind == NodeKind.IDENTIFIER
|
stmt.decoratorKind = decoratorNameToKind(name);
|
||||||
? stringToDecoratorKind((<IdentifierExpression>expression).text)
|
|
||||||
: DecoratorKind.CUSTOM;
|
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1052,34 +1050,65 @@ export enum DecoratorKind {
|
|||||||
CUSTOM,
|
CUSTOM,
|
||||||
GLOBAL,
|
GLOBAL,
|
||||||
OPERATOR,
|
OPERATOR,
|
||||||
|
OPERATOR_BINARY,
|
||||||
|
OPERATOR_PREFIX,
|
||||||
|
OPERATOR_POSTFIX,
|
||||||
UNMANAGED,
|
UNMANAGED,
|
||||||
SEALED,
|
SEALED,
|
||||||
INLINE
|
INLINE
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the decorator kind represented by the specified string. */
|
/** Returns the kind of the specified decorator. Defaults to {@link DecoratorKind.CUSTOM}. */
|
||||||
export function stringToDecoratorKind(str: string): DecoratorKind {
|
export function decoratorNameToKind(name: Expression): DecoratorKind {
|
||||||
assert(str.length);
|
// @global, @inline, @operator, @sealed, @unmanaged
|
||||||
switch (str.charCodeAt(0)) {
|
if (name.kind == NodeKind.IDENTIFIER) {
|
||||||
case CharCode.g: {
|
let nameStr = (<IdentifierExpression>name).text;
|
||||||
if (str == "global") return DecoratorKind.GLOBAL;
|
assert(nameStr.length);
|
||||||
break;
|
switch (nameStr.charCodeAt(0)) {
|
||||||
|
case CharCode.g: {
|
||||||
|
if (nameStr == "global") return DecoratorKind.GLOBAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CharCode.i: {
|
||||||
|
if (nameStr == "inline") return DecoratorKind.INLINE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CharCode.o: {
|
||||||
|
if (nameStr == "operator") return DecoratorKind.OPERATOR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CharCode.s: {
|
||||||
|
if (nameStr == "sealed") return DecoratorKind.SEALED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CharCode.u: {
|
||||||
|
if (nameStr == "unmanaged") return DecoratorKind.UNMANAGED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case CharCode.i: {
|
} else if (
|
||||||
if (str == "inline") return DecoratorKind.INLINE;
|
name.kind == NodeKind.PROPERTYACCESS &&
|
||||||
break;
|
(<PropertyAccessExpression>name).expression.kind == NodeKind.IDENTIFIER
|
||||||
}
|
) {
|
||||||
case CharCode.o: {
|
let nameStr = (<IdentifierExpression>(<PropertyAccessExpression>name).expression).text;
|
||||||
if (str == "operator") return DecoratorKind.OPERATOR;
|
assert(nameStr.length);
|
||||||
break;
|
let propStr = (<PropertyAccessExpression>name).property.text;
|
||||||
}
|
assert(propStr.length);
|
||||||
case CharCode.s: {
|
// @operator.binary, @operator.prefix, @operator.postfix
|
||||||
if (str == "sealed") return DecoratorKind.SEALED;
|
if (nameStr == "operator") {
|
||||||
break;
|
switch (propStr.charCodeAt(0)) {
|
||||||
}
|
case CharCode.b: {
|
||||||
case CharCode.u: {
|
if (propStr == "binary") return DecoratorKind.OPERATOR_BINARY;
|
||||||
if (str == "unmanaged") return DecoratorKind.UNMANAGED;
|
break;
|
||||||
break;
|
}
|
||||||
|
case CharCode.p: {
|
||||||
|
switch (propStr) {
|
||||||
|
case "prefix": return DecoratorKind.OPERATOR_PREFIX;
|
||||||
|
case "postfix": return DecoratorKind.OPERATOR_POSTFIX;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DecoratorKind.CUSTOM;
|
return DecoratorKind.CUSTOM;
|
||||||
|
@ -3940,7 +3940,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
// check operator overloadd
|
// check operator overloadd
|
||||||
let classReference = leftType.classReference;
|
let classReference = leftType.classReference;
|
||||||
if (classReference) {
|
if (classReference) {
|
||||||
let overload = classReference.lookupOverload(OperatorKind.AND);
|
let overload = classReference.lookupOverload(OperatorKind.BITWISE_AND);
|
||||||
if (overload) {
|
if (overload) {
|
||||||
expr = this.compileBinaryOverload(overload, left, right, expression);
|
expr = this.compileBinaryOverload(overload, left, right, expression);
|
||||||
break;
|
break;
|
||||||
@ -4029,7 +4029,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
// check operator overload
|
// check operator overload
|
||||||
let classReference = leftType.classReference;
|
let classReference = leftType.classReference;
|
||||||
if (classReference) {
|
if (classReference) {
|
||||||
let overload = classReference.lookupOverload(OperatorKind.OR);
|
let overload = classReference.lookupOverload(OperatorKind.BITWISE_OR);
|
||||||
if (overload) {
|
if (overload) {
|
||||||
expr = this.compileBinaryOverload(overload, left, right, expression);
|
expr = this.compileBinaryOverload(overload, left, right, expression);
|
||||||
break;
|
break;
|
||||||
@ -4121,7 +4121,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
// check operator overload
|
// check operator overload
|
||||||
let classReference = leftType.classReference;
|
let classReference = leftType.classReference;
|
||||||
if (classReference) {
|
if (classReference) {
|
||||||
let overload = classReference.lookupOverload(OperatorKind.XOR);
|
let overload = classReference.lookupOverload(OperatorKind.BITWISE_XOR);
|
||||||
if (overload) {
|
if (overload) {
|
||||||
expr = this.compileBinaryOverload(overload, left, right, expression);
|
expr = this.compileBinaryOverload(overload, left, right, expression);
|
||||||
break;
|
break;
|
||||||
|
218
src/program.ts
218
src/program.ts
@ -64,7 +64,7 @@ import {
|
|||||||
VariableLikeDeclarationStatement,
|
VariableLikeDeclarationStatement,
|
||||||
VariableStatement,
|
VariableStatement,
|
||||||
|
|
||||||
stringToDecoratorKind
|
decoratorNameToKind
|
||||||
} from "./ast";
|
} from "./ast";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -145,96 +145,122 @@ class TypeAlias {
|
|||||||
/** Represents the kind of an operator overload. */
|
/** Represents the kind of an operator overload. */
|
||||||
export enum OperatorKind {
|
export enum OperatorKind {
|
||||||
INVALID,
|
INVALID,
|
||||||
INDEXED_GET,
|
|
||||||
INDEXED_SET,
|
// indexed access
|
||||||
UNCHECKED_INDEXED_GET,
|
INDEXED_GET, // a[]
|
||||||
UNCHECKED_INDEXED_SET,
|
INDEXED_SET, // a[]=b
|
||||||
ADD,
|
UNCHECKED_INDEXED_GET, // unchecked(a[])
|
||||||
SUB,
|
UNCHECKED_INDEXED_SET, // unchecked(a[]=b)
|
||||||
MUL,
|
|
||||||
DIV,
|
// binary
|
||||||
REM,
|
ADD, // a + b
|
||||||
POW,
|
SUB, // a - b
|
||||||
AND,
|
MUL, // a * b
|
||||||
OR,
|
DIV, // a / b
|
||||||
XOR,
|
REM, // a % b
|
||||||
EQ,
|
POW, // a ** b
|
||||||
NE,
|
BITWISE_AND, // a & b
|
||||||
GT,
|
BITWISE_OR, // a | b
|
||||||
GE,
|
BITWISE_XOR, // a ^ b
|
||||||
LT,
|
BITWISE_SHL, // a << b
|
||||||
LE
|
BITWISE_SHR, // a >> b
|
||||||
|
BITWISE_SHR_U, // a >>> b
|
||||||
|
EQ, // a == b
|
||||||
|
NE, // a != b
|
||||||
|
GT, // a > b
|
||||||
|
GE, // a >= b
|
||||||
|
LT, // a < b
|
||||||
|
LE, // a <= b
|
||||||
|
|
||||||
|
// unary prefix
|
||||||
|
PLUS, // +a
|
||||||
|
MINUS, // -a
|
||||||
|
NOT, // !a
|
||||||
|
BITWISE_NOT, // ~a
|
||||||
|
PREFIX_INC, // ++a
|
||||||
|
PREFIX_DEC, // --a
|
||||||
|
|
||||||
|
// unary postfix
|
||||||
|
POSTFIX_INC, // a++
|
||||||
|
POSTFIX_DEC // a--
|
||||||
|
|
||||||
|
// not overridable:
|
||||||
|
// IDENTITY // a === b
|
||||||
|
// LOGICAL_AND // a && b
|
||||||
|
// LOGICAL_OR // a || b
|
||||||
}
|
}
|
||||||
|
|
||||||
function operatorKindFromString(str: string): OperatorKind {
|
/** Returns the operator kind represented by the specified decorator and string argument. */
|
||||||
assert(str.length);
|
function operatorKindFromDecorator(decoratorKind: DecoratorKind, arg: string): OperatorKind {
|
||||||
switch (str.charCodeAt(0)) {
|
// TODO: currently handles binary only but some differ if unary prefix or postfix
|
||||||
|
assert(arg.length);
|
||||||
|
switch (arg.charCodeAt(0)) {
|
||||||
case CharCode.OPENBRACKET: {
|
case CharCode.OPENBRACKET: {
|
||||||
switch (str) {
|
switch (arg) {
|
||||||
case "[]" : return OperatorKind.INDEXED_GET;
|
case "[]" : return OperatorKind.INDEXED_GET;
|
||||||
case "[]=": return OperatorKind.INDEXED_SET;
|
case "[]=": return OperatorKind.INDEXED_SET;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.OPENBRACE: {
|
case CharCode.OPENBRACE: {
|
||||||
switch (str) {
|
switch (arg) {
|
||||||
case "{}" : return OperatorKind.UNCHECKED_INDEXED_GET;
|
case "{}" : return OperatorKind.UNCHECKED_INDEXED_GET;
|
||||||
case "{}=": return OperatorKind.UNCHECKED_INDEXED_SET;
|
case "{}=": return OperatorKind.UNCHECKED_INDEXED_SET;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.PLUS: {
|
case CharCode.PLUS: {
|
||||||
if (str.length == 1) return OperatorKind.ADD;
|
if (arg.length == 1) return OperatorKind.ADD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.MINUS: {
|
case CharCode.MINUS: {
|
||||||
if (str.length == 1) return OperatorKind.SUB;
|
if (arg.length == 1) return OperatorKind.SUB;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.ASTERISK: {
|
case CharCode.ASTERISK: {
|
||||||
switch (str) {
|
switch (arg) {
|
||||||
case "*" : return OperatorKind.MUL;
|
case "*" : return OperatorKind.MUL;
|
||||||
case "**": return OperatorKind.POW;
|
case "**": return OperatorKind.POW;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.SLASH: {
|
case CharCode.SLASH: {
|
||||||
if (str.length == 1) return OperatorKind.DIV;
|
if (arg.length == 1) return OperatorKind.DIV;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.PERCENT: {
|
case CharCode.PERCENT: {
|
||||||
if (str.length == 1) return OperatorKind.REM;
|
if (arg.length == 1) return OperatorKind.REM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.AMPERSAND: {
|
case CharCode.AMPERSAND: {
|
||||||
if (str.length == 1) return OperatorKind.AND;
|
if (arg.length == 1) return OperatorKind.BITWISE_AND;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.BAR: {
|
case CharCode.BAR: {
|
||||||
if (str.length == 1) return OperatorKind.OR;
|
if (arg.length == 1) return OperatorKind.BITWISE_OR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.CARET: {
|
case CharCode.CARET: {
|
||||||
if (str.length == 1) return OperatorKind.XOR;
|
if (arg.length == 1) return OperatorKind.BITWISE_XOR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.EQUALS: {
|
case CharCode.EQUALS: {
|
||||||
if (str == "==") return OperatorKind.EQ;
|
if (arg == "==") return OperatorKind.EQ;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.EXCLAMATION: {
|
case CharCode.EXCLAMATION: {
|
||||||
if (str == "!=") return OperatorKind.NE;
|
if (arg == "!=") return OperatorKind.NE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.GREATERTHAN: {
|
case CharCode.GREATERTHAN: {
|
||||||
switch (str) {
|
switch (arg) {
|
||||||
case ">" : return OperatorKind.GT;
|
case ">" : return OperatorKind.GT;
|
||||||
case ">=": return OperatorKind.GE;
|
case ">=": return OperatorKind.GE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CharCode.LESSTHAN: {
|
case CharCode.LESSTHAN: {
|
||||||
switch (str) {
|
switch (arg) {
|
||||||
case "<" : return OperatorKind.LT;
|
case "<" : return OperatorKind.LT;
|
||||||
case "<=": return OperatorKind.LE;
|
case "<=": return OperatorKind.LE;
|
||||||
}
|
}
|
||||||
@ -534,24 +560,21 @@ export class Program extends DiagnosticEmitter {
|
|||||||
var presentFlags = DecoratorFlags.NONE;
|
var presentFlags = DecoratorFlags.NONE;
|
||||||
for (let i = 0, k = decorators.length; i < k; ++i) {
|
for (let i = 0, k = decorators.length; i < k; ++i) {
|
||||||
let decorator = decorators[i];
|
let decorator = decorators[i];
|
||||||
if (decorator.name.kind == NodeKind.IDENTIFIER) {
|
let kind = decoratorNameToKind(decorator.name);
|
||||||
let name = (<IdentifierExpression>decorator.name).text;
|
let flag = decoratorKindToFlag(kind);
|
||||||
let kind = stringToDecoratorKind(name);
|
if (flag) {
|
||||||
let flag = decoratorKindToFlag(kind);
|
if (!(acceptedFlags & flag)) {
|
||||||
if (flag) {
|
this.error(
|
||||||
if (!(acceptedFlags & flag)) {
|
DiagnosticCode.Decorator_0_is_not_valid_here,
|
||||||
this.error(
|
decorator.range, decorator.name.range.toString()
|
||||||
DiagnosticCode.Decorator_0_is_not_valid_here,
|
);
|
||||||
decorator.range, name
|
} else if (presentFlags & flag) {
|
||||||
);
|
this.error(
|
||||||
} else if (presentFlags & flag) {
|
DiagnosticCode.Duplicate_decorator,
|
||||||
this.error(
|
decorator.range, decorator.name.range.toString()
|
||||||
DiagnosticCode.Duplicate_decorator,
|
);
|
||||||
decorator.range, name
|
} else {
|
||||||
);
|
presentFlags |= flag;
|
||||||
} else {
|
|
||||||
presentFlags |= flag;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -796,7 +819,7 @@ export class Program extends DiagnosticEmitter {
|
|||||||
var decoratorFlags = DecoratorFlags.NONE;
|
var decoratorFlags = DecoratorFlags.NONE;
|
||||||
if (decorators) {
|
if (decorators) {
|
||||||
decoratorFlags = this.filterDecorators(decorators,
|
decoratorFlags = this.filterDecorators(decorators,
|
||||||
DecoratorFlags.OPERATOR |
|
DecoratorFlags.OPERATOR_BINARY |
|
||||||
DecoratorFlags.INLINE
|
DecoratorFlags.INLINE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -887,50 +910,54 @@ export class Program extends DiagnosticEmitter {
|
|||||||
prototype: FunctionPrototype,
|
prototype: FunctionPrototype,
|
||||||
classPrototype: ClassPrototype
|
classPrototype: ClassPrototype
|
||||||
): void {
|
): void {
|
||||||
// handle operator annotations. operators are either instance methods taking
|
|
||||||
// a second argument of the instance's type or static methods taking two
|
|
||||||
// arguments of the instance's type. return values vary depending on the
|
|
||||||
// operation.
|
|
||||||
if (decorators) {
|
if (decorators) {
|
||||||
for (let i = 0, k = decorators.length; i < k; ++i) {
|
for (let i = 0, k = decorators.length; i < k; ++i) {
|
||||||
let decorator = decorators[i];
|
let decorator = decorators[i];
|
||||||
if (decorator.decoratorKind == DecoratorKind.OPERATOR) {
|
switch (decorator.decoratorKind) {
|
||||||
let numArgs = decorator.arguments && decorator.arguments.length || 0;
|
case DecoratorKind.OPERATOR:
|
||||||
if (numArgs == 1) {
|
case DecoratorKind.OPERATOR_BINARY:
|
||||||
let firstArg = (<Expression[]>decorator.arguments)[0];
|
case DecoratorKind.OPERATOR_PREFIX:
|
||||||
if (
|
case DecoratorKind.OPERATOR_POSTFIX: {
|
||||||
firstArg.kind == NodeKind.LITERAL &&
|
let numArgs = decorator.arguments && decorator.arguments.length || 0;
|
||||||
(<LiteralExpression>firstArg).literalKind == LiteralKind.STRING
|
if (numArgs == 1) {
|
||||||
) {
|
let firstArg = (<Expression[]>decorator.arguments)[0];
|
||||||
let kind = operatorKindFromString((<StringLiteralExpression>firstArg).value);
|
if (
|
||||||
if (kind == OperatorKind.INVALID) {
|
firstArg.kind == NodeKind.LITERAL &&
|
||||||
this.error(
|
(<LiteralExpression>firstArg).literalKind == LiteralKind.STRING
|
||||||
DiagnosticCode.Operation_not_supported,
|
) {
|
||||||
firstArg.range
|
let kind = operatorKindFromDecorator(
|
||||||
|
decorator.decoratorKind,
|
||||||
|
(<StringLiteralExpression>firstArg).value
|
||||||
);
|
);
|
||||||
} else {
|
if (kind == OperatorKind.INVALID) {
|
||||||
let overloads = classPrototype.overloadPrototypes;
|
|
||||||
if (overloads.has(kind)) {
|
|
||||||
this.error(
|
this.error(
|
||||||
DiagnosticCode.Duplicate_function_implementation,
|
DiagnosticCode.Operation_not_supported,
|
||||||
firstArg.range
|
firstArg.range
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
prototype.operatorKind = kind;
|
let overloads = classPrototype.overloadPrototypes;
|
||||||
overloads.set(kind, prototype);
|
if (overloads.has(kind)) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Duplicate_function_implementation,
|
||||||
|
firstArg.range
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
prototype.operatorKind = kind;
|
||||||
|
overloads.set(kind, prototype);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.String_literal_expected,
|
||||||
|
firstArg.range
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.error(
|
this.error(
|
||||||
DiagnosticCode.String_literal_expected,
|
DiagnosticCode.Expected_0_arguments_but_got_1,
|
||||||
firstArg.range
|
decorator.range, "1", numArgs.toString(0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this.error(
|
|
||||||
DiagnosticCode.Expected_0_arguments_but_got_1,
|
|
||||||
decorator.range, "1", numArgs.toString(0)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2382,20 +2409,27 @@ export enum DecoratorFlags {
|
|||||||
NONE = 0,
|
NONE = 0,
|
||||||
/** Is a program global. */
|
/** Is a program global. */
|
||||||
GLOBAL = 1 << 0,
|
GLOBAL = 1 << 0,
|
||||||
/** Is an operator overload. */
|
/** Is a binary operator overload. */
|
||||||
OPERATOR = 1 << 1,
|
OPERATOR_BINARY = 1 << 1,
|
||||||
|
/** Is a unary prefix operator overload. */
|
||||||
|
OPERATOR_PREFIX = 1 << 2,
|
||||||
|
/** Is a unary postfix operator overload. */
|
||||||
|
OPERATOR_POSTFIX = 1 << 3,
|
||||||
/** Is an unmanaged class. */
|
/** Is an unmanaged class. */
|
||||||
UNMANAGED = 1 << 2,
|
UNMANAGED = 1 << 4,
|
||||||
/** Is a sealed class. */
|
/** Is a sealed class. */
|
||||||
SEALED = 1 << 3,
|
SEALED = 1 << 5,
|
||||||
/** Is always inlined. */
|
/** Is always inlined. */
|
||||||
INLINE = 1 << 4
|
INLINE = 1 << 6
|
||||||
}
|
}
|
||||||
|
|
||||||
export function decoratorKindToFlag(kind: DecoratorKind): DecoratorFlags {
|
export function decoratorKindToFlag(kind: DecoratorKind): DecoratorFlags {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case DecoratorKind.GLOBAL: return DecoratorFlags.GLOBAL;
|
case DecoratorKind.GLOBAL: return DecoratorFlags.GLOBAL;
|
||||||
case DecoratorKind.OPERATOR: return DecoratorFlags.OPERATOR;
|
case DecoratorKind.OPERATOR:
|
||||||
|
case DecoratorKind.OPERATOR_BINARY: return DecoratorFlags.OPERATOR_BINARY;
|
||||||
|
case DecoratorKind.OPERATOR_PREFIX: return DecoratorFlags.OPERATOR_PREFIX;
|
||||||
|
case DecoratorKind.OPERATOR_POSTFIX: return DecoratorFlags.OPERATOR_POSTFIX;
|
||||||
case DecoratorKind.UNMANAGED: return DecoratorFlags.UNMANAGED;
|
case DecoratorKind.UNMANAGED: return DecoratorFlags.UNMANAGED;
|
||||||
case DecoratorKind.SEALED: return DecoratorFlags.SEALED;
|
case DecoratorKind.SEALED: return DecoratorFlags.SEALED;
|
||||||
case DecoratorKind.INLINE: return DecoratorFlags.INLINE;
|
case DecoratorKind.INLINE: return DecoratorFlags.INLINE;
|
||||||
|
10
std/assembly.d.ts
vendored
10
std/assembly.d.ts
vendored
@ -573,8 +573,16 @@ declare const Mathf: IMath<f32>;
|
|||||||
/** Annotates an element as a program global. */
|
/** Annotates an element as a program global. */
|
||||||
declare function global(target: Function, propertyKey: string, descriptor: any): void;
|
declare function global(target: Function, propertyKey: string, descriptor: any): void;
|
||||||
|
|
||||||
/** Annotates a method as an operator overload for the specified `token`. */
|
/** Annotates a method as a binary operator overload for the specified `token`. */
|
||||||
declare function operator(token: string): (target: any, propertyKey: string, descriptor: any) => void;
|
declare function operator(token: string): (target: any, propertyKey: string, descriptor: any) => void;
|
||||||
|
declare namespace operator {
|
||||||
|
/** Annotates a method as a binary operator overload for the specified `token`. */
|
||||||
|
export function binary(token: string): (target: any, propertyKey: string, descriptor: any) => void;
|
||||||
|
/** Annotates a method as an unary prefix operator overload for the specified `token`. */
|
||||||
|
export function prefix(token: string): (target: any, propertyKey: string, descriptor: any) => void;
|
||||||
|
/** Annotates a method as an unary postfix operator overload for the specified `token`. */
|
||||||
|
export function postfix(token: string): (target: any, propertyKey: string, descriptor: any) => void;
|
||||||
|
}
|
||||||
|
|
||||||
/** Annotates a class as being unmanaged with limited capabilities. */
|
/** Annotates a class as being unmanaged with limited capabilities. */
|
||||||
declare function unmanaged(target: Function): any;
|
declare function unmanaged(target: Function): any;
|
||||||
|
10
tests/parser/decorators.ts
Normal file
10
tests/parser/decorators.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@global
|
||||||
|
@operator("+")
|
||||||
|
@operator.binary("-")
|
||||||
|
@operator.prefix("~")
|
||||||
|
@operator.postfix("++")
|
||||||
|
@unmanaged
|
||||||
|
@sealed
|
||||||
|
@inline
|
||||||
|
@custom
|
||||||
|
function a(): void {}
|
10
tests/parser/decorators.ts.fixture.ts
Normal file
10
tests/parser/decorators.ts.fixture.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@global
|
||||||
|
@operator("+")
|
||||||
|
@operator.binary("-")
|
||||||
|
@operator.prefix("~")
|
||||||
|
@operator.postfix("++")
|
||||||
|
@unmanaged
|
||||||
|
@sealed
|
||||||
|
@inline
|
||||||
|
@custom
|
||||||
|
function a(): void {}
|
Loading…
x
Reference in New Issue
Block a user