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: main
Choose a base ref
...
head repository: AssemblyScript/assemblyscript
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: implement-type-infer
Choose a head ref
Able to merge. These branches can be automatically merged.
  • 4 commits
  • 9 files changed
  • 1 contributor

Commits on Oct 28, 2024

  1. fix parser

    HerrCai0907 committed Oct 28, 2024
    Copy the full SHA
    83fa58a View commit details
  2. implement

    HerrCai0907 committed Oct 28, 2024
    Copy the full SHA
    37ca029 View commit details
  3. test

    HerrCai0907 committed Oct 28, 2024
    Copy the full SHA
    c9cdecf View commit details
  4. fix

    HerrCai0907 committed Oct 28, 2024
    Copy the full SHA
    e4e6267 View commit details
16 changes: 16 additions & 0 deletions src/ast.ts
Original file line number Diff line number Diff line change
@@ -51,6 +51,7 @@ export const enum NodeKind {
// types
NamedType,
FunctionType,
InferredType,
TypeName,
TypeParameter,
Parameter,
@@ -168,6 +169,10 @@ export abstract class Node {
return new NamedTypeNode(Node.createSimpleTypeName("", range), null, false, range);
}

static createInferredType(expr: Expression): InferredTypeNode {
return new InferredTypeNode(expr, expr.range);
}

static createTypeParameter(
name: IdentifierExpression,
extendsType: NamedTypeNode | null,
@@ -929,6 +934,17 @@ export class FunctionTypeNode extends TypeNode {
}
}

export class InferredTypeNode extends TypeNode {
constructor(
/** Function parameters. */
public expr: Expression,
/** Source range. */
range: Range
) {
super(NodeKind.InferredType, false, range);
}
}

/** Represents a type parameter. */
export class TypeParameterNode extends Node {
constructor(
1 change: 1 addition & 0 deletions src/diagnosticMessages.json
Original file line number Diff line number Diff line change
@@ -52,6 +52,7 @@
"Initializer, definitive assignment or nullable type expected.": 238,
"Definitive assignment has no effect on local variables.": 239,
"Ambiguous operator overload '{0}' (conflicting overloads '{1}' and '{2}').": 240,
"Cannot infer type.": 241,

"Importing the table disables some indirect call optimizations.": 901,
"Exporting the table disables some indirect call optimizations.": 902,
5 changes: 0 additions & 5 deletions src/parser.ts
Original file line number Diff line number Diff line change
@@ -2379,11 +2379,6 @@ export class Parser extends DiagnosticEmitter {
if (tn.skip(Token.Colon)) {
type = this.parseType(tn);
if (!type) return null;
} else {
this.error(
DiagnosticCode.Type_expected,
tn.range()
); // recoverable
}
let initializer: Expression | null = null;
if (tn.skip(Token.Equals)) {
6 changes: 5 additions & 1 deletion src/program.ts
Original file line number Diff line number Diff line change
@@ -3999,7 +3999,11 @@ export class PropertyPrototype extends DeclaredElement {
// override stub at the interface needs to handle both interchangeably.
let nativeRange = Source.native.range;
let typeNode = fieldDeclaration.type;
if (!typeNode) typeNode = Node.createOmittedType(fieldDeclaration.name.range.atEnd);
let initializer = fieldDeclaration.initializer;
if (!typeNode) {
const defaultTypeNode = initializer ? Node.createInferredType(initializer) : Node.createOmittedType(fieldDeclaration.name.range.atEnd);
typeNode = defaultTypeNode;
}
let getterDeclaration = new MethodDeclaration( // get name(): type
fieldDeclaration.name,
fieldDeclaration.decorators,
34 changes: 33 additions & 1 deletion src/resolver.ts
Original file line number Diff line number Diff line change
@@ -76,7 +76,8 @@ import {
NewExpression,
ArrayLiteralExpression,
ArrowKind,
ExpressionStatement
ExpressionStatement,
InferredTypeNode
} from "./ast";

import {
@@ -169,6 +170,10 @@ export class Resolver extends DiagnosticEmitter {
resolved = this.resolveFunctionType(<FunctionTypeNode>node, flow, ctxElement, ctxTypes, reportMode);
break;
}
case NodeKind.InferredType: {
resolved = this.inferExpressionType((<InferredTypeNode>node).expr);
break;
}
default: assert(false);
}
node.currentlyResolving = false;
@@ -3742,4 +3747,31 @@ export class Resolver extends DiagnosticEmitter {
}
return typeArgumentNodes[0];
}

private inferExpressionType(expr: Expression): Type | null {
switch(expr.kind) {
case NodeKind.Literal:
switch((<LiteralExpression>expr).literalKind) {
case LiteralKind.Integer:
return this.determineIntegerLiteralType(<IntegerLiteralExpression>expr, false, Type.auto);
case LiteralKind.Float:
return Type.f64;
}
break;
case NodeKind.Binary:
switch((<BinaryExpression>expr).operator) {
case Token.Equals_Equals:
case Token.Equals_Equals_Equals:
case Token.Exclamation_Equals:
case Token.Exclamation_Equals_Equals:
return Type.bool;
}
break;
case NodeKind.True:
case NodeKind.False:
return Type.bool;
}
this.error(DiagnosticCode.Cannot_infer_type, expr.range);
return null;
}
}
Loading