Skip to content

Commit 13dfaf8

Browse files
authored
Merge branch 'main' into opt-zero-init
2 parents 492c866 + 282b7e8 commit 13dfaf8

18 files changed

+3764
-2306
lines changed

NOTICE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ under the licensing terms detailed in LICENSE:
6161
* Jonas Minnberg <[email protected]>
6262
* Kam Chehresa <[email protected]>
6363
* Rui Jin <[email protected]>
64+
* Mopsgamer <[email protected]>
6465

6566
Portions of this software are derived from third-party works licensed under
6667
the following terms:

bin/asinit.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ if (/^(\.\.[/\\])*node_modules[/\\]assemblyscript[/\\]/.test(tsconfigBase)) {
100100
}
101101
const entryFile = path.join(assemblyDir, "index.ts");
102102
const buildDir = path.join(projectDir, "build");
103-
const testsDir = path.join(projectDir, "tests");
103+
const testsDir = path.join(projectDir, "test");
104104
const gitignoreFile = path.join(buildDir, ".gitignore");
105105
const packageFile = path.join(projectDir, "package.json");
106106

@@ -358,7 +358,7 @@ function ensurePackageJson() {
358358
"asbuild:debug": buildDebug,
359359
"asbuild:release": buildRelease,
360360
"asbuild": buildAll,
361-
"test": "node tests",
361+
"test": "node --test",
362362
"start": "npx serve ."
363363
},
364364
"devDependencies": {
@@ -390,7 +390,7 @@ function ensurePackageJson() {
390390
updated = true;
391391
}
392392
if (!scripts["test"] || scripts["test"] == npmDefaultTest) {
393-
scripts["test"] = "node tests";
393+
scripts["test"] = "node --test";
394394
pkg["scripts"] = scripts;
395395
updated = true;
396396
}
@@ -416,7 +416,7 @@ function ensurePackageJson() {
416416
}
417417

418418
function ensureTestsDirectory() {
419-
console.log("- Making sure that the 'tests' directory exists...");
419+
console.log("- Making sure that the 'test' directory exists...");
420420
if (!fs.existsSync(testsDir)) {
421421
fs.mkdirSync(testsDir);
422422
console.log(stdoutColors.green(" Created: ") + testsDir);
@@ -427,13 +427,16 @@ function ensureTestsDirectory() {
427427
}
428428

429429
function ensureTestsIndexJs() {
430-
console.log("- Making sure that 'tests/index.js' exists...");
430+
console.log("- Making sure that 'test/index.js' exists...");
431431
if (!fs.existsSync(testsIndexFile)) {
432432
fs.writeFileSync(testsIndexFile, [
433-
"import assert from \"assert\";",
433+
"import assert from \"node:assert/strict\";",
434+
"import { it } from \"node:test\";",
434435
"import { add } from \"../build/debug.js\";",
435-
"assert.strictEqual(add(1, 2), 3);",
436-
"console.log(\"ok\");"
436+
"",
437+
"it(\"add\", () => {",
438+
" assert.equal(add(1, 2), 3);",
439+
"});"
437440
].join("\n") + "\n");
438441
console.log(stdoutColors.green(" Created: ") + testsIndexFile);
439442
} else {

src/common.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ export namespace CommonNames {
194194
export const ASC_VERSION_MAJOR = "ASC_VERSION_MAJOR";
195195
export const ASC_VERSION_MINOR = "ASC_VERSION_MINOR";
196196
export const ASC_VERSION_PATCH = "ASC_VERSION_PATCH";
197+
// enums
198+
export const EnumToString = "__enum_to_string";
197199
// classes
198200
export const I8 = "I8";
199201
export const I16 = "I16";

src/compiler.ts

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1523,6 +1523,49 @@ export class Compiler extends DiagnosticEmitter {
15231523
return true;
15241524
}
15251525

1526+
private ensureEnumToString(enumElement: Enum, reportNode: Node): string | null {
1527+
if (enumElement.toStringFunctionName) return enumElement.toStringFunctionName;
1528+
1529+
if (!this.compileEnum(enumElement)) return null;
1530+
if (enumElement.is(CommonFlags.Const)) {
1531+
this.errorRelated(
1532+
DiagnosticCode.A_const_enum_member_can_only_be_accessed_using_a_string_literal,
1533+
reportNode.range, enumElement.identifierNode.range
1534+
);
1535+
return null;
1536+
}
1537+
1538+
let members = enumElement.members;
1539+
if (!members) return null;
1540+
1541+
let module = this.module;
1542+
const isInline = enumElement.hasDecorator(DecoratorFlags.Inline);
1543+
1544+
const functionName = `${enumElement.internalName}#${CommonNames.EnumToString}`;
1545+
enumElement.toStringFunctionName = functionName;
1546+
1547+
let exprs = new Array<ExpressionRef>();
1548+
// when the values are the same, TS returns the last enum value name that appears
1549+
for (let _keys = Map_keys(members), _values = Map_values(members), i = 1, k = _keys.length; i <= k; ++i) {
1550+
let enumValueName = unchecked(_keys[k - i]);
1551+
let member = unchecked(_values[k - i]);
1552+
if (member.kind != ElementKind.EnumValue) continue;
1553+
let enumValue = <EnumValue>member;
1554+
const enumValueExpr = isInline
1555+
? module.i32(i64_low(enumValue.constantIntegerValue))
1556+
: module.global_get(enumValue.internalName, TypeRef.I32);
1557+
let expr = module.if(
1558+
module.binary(BinaryOp.EqI32, enumValueExpr, module.local_get(0, TypeRef.I32)),
1559+
module.return(this.ensureStaticString(enumValueName))
1560+
);
1561+
exprs.push(expr);
1562+
}
1563+
exprs.push(module.unreachable());
1564+
module.addFunction(functionName, TypeRef.I32, TypeRef.I32, null, module.block(null, exprs, TypeRef.I32));
1565+
1566+
return functionName;
1567+
}
1568+
15261569
// === Functions ================================================================================
15271570

15281571
/** Compiles a priorly resolved function. */
@@ -7093,7 +7136,17 @@ export class Compiler extends DiagnosticEmitter {
70937136
): ExpressionRef {
70947137
let module = this.module;
70957138
let targetExpression = expression.expression;
7096-
let targetType = this.resolver.resolveExpression(targetExpression, this.currentFlow); // reports
7139+
let resolver = this.resolver;
7140+
let targetElement = resolver.lookupExpression(targetExpression, this.currentFlow, Type.auto, ReportMode.Swallow);
7141+
if (targetElement && targetElement.kind == ElementKind.Enum) {
7142+
const elementExpr = this.compileExpression(expression.elementExpression, Type.i32, Constraints.ConvImplicit);
7143+
const toStringFunctionName = this.ensureEnumToString(<Enum>targetElement, expression);
7144+
this.currentType = this.program.stringInstance.type;
7145+
if (toStringFunctionName == null) return module.unreachable();
7146+
return module.call(toStringFunctionName, [ elementExpr ], TypeRef.I32);
7147+
}
7148+
7149+
let targetType = resolver.resolveExpression(targetExpression, this.currentFlow);
70977150
if (targetType) {
70987151
let classReference = targetType.getClassOrWrapper(this.program);
70997152
if (classReference) {

src/diagnosticMessages.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@
174174
"Type '{0}' has no property '{1}'.": 2460,
175175
"The '{0}' operator cannot be applied to type '{1}'.": 2469,
176176
"In 'const' enum declarations member initializer must be constant expression.": 2474,
177+
"A const enum member can only be accessed using a string literal.": 2476,
177178
"Export declaration conflicts with exported declaration of '{0}'.": 2484,
178179
"'{0}' is referenced directly or indirectly in its own base expression.": 2506,
179180
"Cannot create an instance of an abstract class.": 2511,

src/program.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3449,7 +3449,7 @@ export class Namespace extends DeclaredElement {
34493449

34503450
/** An enum. */
34513451
export class Enum extends TypedElement {
3452-
3452+
toStringFunctionName: string | null = null;
34533453
/** Constructs a new enum. */
34543454
constructor(
34553455
/** Simple name. */
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"asc_flags": [],
3+
"stderr": [
4+
"TS2476: A const enum member can only be accessed using a string literal.",
5+
"EOF"
6+
]
7+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const enum CE {
2+
CE0,
3+
CE1,
4+
CE2,
5+
}
6+
7+
assert(CE[CE.CE0] === "CE0");
8+
9+
ERROR("EOF");

0 commit comments

Comments
 (0)