Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: AssemblyScript/assemblyscript
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.27.21
Choose a base ref
...
head repository: AssemblyScript/assemblyscript
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.27.22
Choose a head ref
  • 1 commit
  • 9 files changed
  • 1 contributor

Commits on Nov 23, 2023

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1e0466e View commit details
Showing with 802 additions and 58 deletions.
  1. +34 −18 src/compiler.ts
  2. +36 −1 src/flow.ts
  3. +3 −3 src/program.ts
  4. +49 −27 src/resolver.ts
  5. +7 −0 tests/compiler/typealias-errors.json
  6. +4 −0 tests/compiler/typealias-errors.ts
  7. +363 −7 tests/compiler/typealias.debug.wat
  8. +280 −2 tests/compiler/typealias.release.wat
  9. +26 −0 tests/compiler/typealias.ts
52 changes: 34 additions & 18 deletions src/compiler.ts
Original file line number Diff line number Diff line change
@@ -93,7 +93,8 @@ import {
PropertyPrototype,
IndexSignature,
File,
mangleInternalName
mangleInternalName,
TypeDefinition
} from "./program";

import {
@@ -180,7 +181,8 @@ import {

findDecorator,
isTypeOmitted,
Source
Source,
TypeDeclaration
} from "./ast";

import {
@@ -1156,7 +1158,7 @@ export class Compiler extends DiagnosticEmitter {

// Resolve type if annotated
if (typeNode) {
let resolvedType = this.resolver.resolveType(typeNode, global.parent); // reports
let resolvedType = this.resolver.resolveType(typeNode, null, global.parent); // reports
if (!resolvedType) {
global.set(CommonFlags.Errored);
pendingElements.delete(global);
@@ -2238,13 +2240,7 @@ export class Compiler extends DiagnosticEmitter {
break;
}
case NodeKind.TypeDeclaration: {
// TODO: integrate inner type declaration into flow
this.error(
DiagnosticCode.Not_implemented_0,
statement.range,
"Inner type alias"
);
stmt = module.unreachable();
stmt = this.compileTypeDeclaration(<TypeDeclaration>statement);
break;
}
case NodeKind.Module: {
@@ -2305,6 +2301,24 @@ export class Compiler extends DiagnosticEmitter {
return this.module.flatten(stmts);
}

private compileTypeDeclaration(statement: TypeDeclaration): ExpressionRef {
let flow = this.currentFlow;
let name = statement.name.text;
let existedTypeAlias = flow.lookupScopedTypeAlias(name);
if (existedTypeAlias) {
this.errorRelated(
DiagnosticCode.Duplicate_identifier_0,
statement.range,
existedTypeAlias.declaration.range,
name
);
return this.module.unreachable();
}
let element = new TypeDefinition(name, flow.sourceFunction, statement, DecoratorFlags.None);
flow.addScopedTypeAlias(name, element);
return this.module.nop();
}

private compileBreakStatement(
statement: BreakStatement
): ExpressionRef {
@@ -2962,7 +2976,7 @@ export class Compiler extends DiagnosticEmitter {
let initializerNode = declaration.initializer;
if (typeNode) {
type = resolver.resolveType( // reports
typeNode,
typeNode, flow,
flow.sourceFunction,
cloneMap(flow.contextualTypeArguments)
);
@@ -3729,7 +3743,7 @@ export class Compiler extends DiagnosticEmitter {
case AssertionKind.As: {
let flow = this.currentFlow;
let toType = this.resolver.resolveType( // reports
assert(expression.toType),
assert(expression.toType), flow,
flow.sourceFunction,
cloneMap(flow.contextualTypeArguments)
);
@@ -6162,6 +6176,7 @@ export class Compiler extends DiagnosticEmitter {
typeArguments = this.resolver.resolveTypeArguments(
assert(typeParameterNodes),
typeArgumentNodes,
this.currentFlow,
this.currentFlow.sourceFunction.parent,
cloneMap(this.currentFlow.contextualTypeArguments), // don't update
expression
@@ -7085,7 +7100,7 @@ export class Compiler extends DiagnosticEmitter {
let parameterNode = parameterNodes[i];
if (!isTypeOmitted(parameterNode.type)) {
let resolvedType = this.resolver.resolveType(
parameterNode.type,
parameterNode.type, flow,
sourceFunction.parent,
contextualTypeArguments
);
@@ -7105,7 +7120,7 @@ export class Compiler extends DiagnosticEmitter {
let returnType = contextualSignature.returnType;
if (!isTypeOmitted(signatureNode.returnType)) {
let resolvedType = this.resolver.resolveType(
signatureNode.returnType,
signatureNode.returnType, flow,
sourceFunction.parent,
contextualTypeArguments
);
@@ -7135,7 +7150,7 @@ export class Compiler extends DiagnosticEmitter {
return module.unreachable();
}
let resolvedType = this.resolver.resolveType(
thisTypeNode,
thisTypeNode, flow,
sourceFunction.parent,
contextualTypeArguments
);
@@ -7522,7 +7537,7 @@ export class Compiler extends DiagnosticEmitter {
if (isType.kind == NodeKind.NamedType) {
let namedType = <NamedTypeNode>isType;
if (!(namedType.isNullable || namedType.hasTypeArguments)) {
let element = this.resolver.resolveTypeName(namedType.name, flow.sourceFunction, ReportMode.Swallow);
let element = this.resolver.resolveTypeName(namedType.name, flow, flow.sourceFunction, ReportMode.Swallow);
if (element && element.kind == ElementKind.ClassPrototype) {
let prototype = <ClassPrototype>element;
if (prototype.is(CommonFlags.Generic)) {
@@ -7534,7 +7549,7 @@ export class Compiler extends DiagnosticEmitter {

// Fall back to `instanceof TYPE`
let expectedType = this.resolver.resolveType(
expression.isType,
expression.isType, flow,
flow.sourceFunction,
cloneMap(flow.contextualTypeArguments)
);
@@ -8686,7 +8701,7 @@ export class Compiler extends DiagnosticEmitter {
let flow = this.currentFlow;

// obtain the class being instantiated
let target = this.resolver.resolveTypeName(expression.typeName, flow.sourceFunction);
let target = this.resolver.resolveTypeName(expression.typeName, flow, flow.sourceFunction);
if (!target) return module.unreachable();
if (target.kind != ElementKind.ClassPrototype) {
this.error(
@@ -8722,6 +8737,7 @@ export class Compiler extends DiagnosticEmitter {
classInstance = this.resolver.resolveClassInclTypeArguments(
classPrototype,
typeArguments,
flow,
flow.sourceFunction.parent, // relative to caller
cloneMap(flow.contextualTypeArguments),
expression
37 changes: 36 additions & 1 deletion src/flow.ts
Original file line number Diff line number Diff line change
@@ -31,7 +31,8 @@ import {
TypedElement,
mangleInternalName,
Property,
PropertyPrototype
PropertyPrototype,
TypeDefinition
} from "./program";

import {
@@ -250,6 +251,8 @@ export class Flow {
breakLabel: string | null = null;
/** Scoped local variables. */
scopedLocals: Map<string,Local> | null = null;
/** Scoped type alias. */
scopedTypeAlias: Map<string,TypeDefinition> | null = null;
/** Local flags. */
localFlags: LocalFlags[] = [];
/** Field flags on `this`. Constructors only. */
@@ -405,6 +408,38 @@ export class Flow {
falseFlows.set(condExpr, falseFlow);
}

addScopedTypeAlias(name: string, definition: TypeDefinition): void {
let scopedTypeAlias = this.scopedTypeAlias;
if (!scopedTypeAlias) this.scopedTypeAlias = scopedTypeAlias = new Map();
scopedTypeAlias.set(name, definition);
}

lookupScopedTypeAlias(name: string): TypeDefinition | null {
let current: Flow | null = this;
do {
let scopedTypeAlias = current.scopedTypeAlias;
if (scopedTypeAlias && scopedTypeAlias.has(name)) {
return assert(scopedTypeAlias.get(name));
}
current = current.parent;
} while (current);
return null;
}

lookupTypeAlias(name: string): TypeDefinition | null {
let definition: TypeDefinition | null = null;
if (definition = this.lookupScopedTypeAlias(name)) return definition;

let sourceParent = this.sourceFunction.parent;
if (sourceParent.kind == ElementKind.Function) {
// lookup parent function.
let parentFunction = <Function>sourceParent;
return parentFunction.flow.lookupTypeAlias(name);
}

return null;
}

/** Gets a free temporary local of the specified type. */
getTempLocal(type: Type): Local {
let local = this.targetFunction.addLocal(type);
6 changes: 3 additions & 3 deletions src/program.ts
Original file line number Diff line number Diff line change
@@ -1308,7 +1308,7 @@ export class Program extends DiagnosticEmitter {
for (let i = 0, k = queuedExtends.length; i < k; ++i) {
let thisPrototype = queuedExtends[i];
let extendsNode = assert(thisPrototype.extendsNode); // must be present if in queuedExtends
let baseElement = resolver.resolveTypeName(extendsNode.name, thisPrototype.parent);
let baseElement = resolver.resolveTypeName(extendsNode.name, null, thisPrototype.parent);
if (!baseElement) continue;
if (thisPrototype.kind == ElementKind.ClassPrototype) {
if (baseElement.kind == ElementKind.ClassPrototype) {
@@ -1405,7 +1405,7 @@ export class Program extends DiagnosticEmitter {
let implementsNodes = assert(thisPrototype.implementsNodes); // must be present if in queuedImplements
for (let j = 0, l = implementsNodes.length; j < l; ++j) {
let implementsNode = implementsNodes[j];
let interfaceElement = resolver.resolveTypeName(implementsNode.name, thisPrototype.parent);
let interfaceElement = resolver.resolveTypeName(implementsNode.name, null, thisPrototype.parent);
if (!interfaceElement) continue;
if (interfaceElement.kind == ElementKind.InterfacePrototype) {
let interfacePrototype = <InterfacePrototype>interfaceElement;
@@ -3383,7 +3383,7 @@ export class TypeDefinition extends TypedElement {
constructor(
/** Simple name. */
name: string,
/** Parent element, usually a file or namespace. */
/** Parent element. */
parent: Element,
/** Declaration reference. */
declaration: TypeDeclaration,
Loading