mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 23:12:19 +00:00
Refactor resolve infrastructure to its own file
This has become a little clumsy over time. Doesn't hurt to have it in its own place to get a grasp of it more easily.
This commit is contained in:
parent
585d246165
commit
cd14b296ce
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
@ -2794,7 +2794,7 @@ export function compileAllocate(
|
|||||||
return module.createUnreachable();
|
return module.createUnreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
var allocateInstance = (<FunctionPrototype>allocatePrototype).resolve(); // reports
|
var allocateInstance = compiler.resolver.resolveFunction(<FunctionPrototype>allocatePrototype, null);
|
||||||
if (!(allocateInstance && compiler.compileFunction(allocateInstance))) return module.createUnreachable();
|
if (!(allocateInstance && compiler.compileFunction(allocateInstance))) return module.createUnreachable();
|
||||||
|
|
||||||
compiler.currentType = classInstance.type;
|
compiler.currentType = classInstance.type;
|
||||||
@ -2825,7 +2825,7 @@ export function compileAbort(
|
|||||||
var abortPrototype = program.elementsLookup.get(abortInternalName); // might be intended
|
var abortPrototype = program.elementsLookup.get(abortInternalName); // might be intended
|
||||||
if (!abortPrototype || abortPrototype.kind != ElementKind.FUNCTION_PROTOTYPE) return module.createUnreachable();
|
if (!abortPrototype || abortPrototype.kind != ElementKind.FUNCTION_PROTOTYPE) return module.createUnreachable();
|
||||||
|
|
||||||
var abortInstance = (<FunctionPrototype>abortPrototype).resolve(); // reports
|
var abortInstance = compiler.resolver.resolveFunction(<FunctionPrototype>abortPrototype, null);
|
||||||
if (!(abortInstance && compiler.compileFunction(abortInstance))) return module.createUnreachable();
|
if (!(abortInstance && compiler.compileFunction(abortInstance))) return module.createUnreachable();
|
||||||
|
|
||||||
var messageArg = message != null
|
var messageArg = message != null
|
||||||
|
140
src/compiler.ts
140
src/compiler.ts
@ -73,6 +73,10 @@ import {
|
|||||||
DecoratorFlags
|
DecoratorFlags
|
||||||
} from "./program";
|
} from "./program";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Resolver
|
||||||
|
} from "./resolver";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Token,
|
Token,
|
||||||
operatorTokenToString
|
operatorTokenToString
|
||||||
@ -250,6 +254,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
/** Program reference. */
|
/** Program reference. */
|
||||||
program: Program;
|
program: Program;
|
||||||
|
/** Resolver reference. */
|
||||||
|
resolver: Resolver;
|
||||||
/** Provided options. */
|
/** Provided options. */
|
||||||
options: Options;
|
options: Options;
|
||||||
/** Module instance being compiled. */
|
/** Module instance being compiled. */
|
||||||
@ -288,6 +294,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
constructor(program: Program, options: Options | null = null) {
|
constructor(program: Program, options: Options | null = null) {
|
||||||
super(program.diagnostics);
|
super(program.diagnostics);
|
||||||
this.program = program;
|
this.program = program;
|
||||||
|
this.resolver = program.resolver;
|
||||||
if (!options) options = new Options();
|
if (!options) options = new Options();
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.memoryOffset = i64_new(
|
this.memoryOffset = i64_new(
|
||||||
@ -430,7 +437,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
(noTreeShaking || (isEntry && statement.is(CommonFlags.EXPORT))) &&
|
(noTreeShaking || (isEntry && statement.is(CommonFlags.EXPORT))) &&
|
||||||
!(<ClassDeclaration>statement).isGeneric
|
!(<ClassDeclaration>statement).isGeneric
|
||||||
) {
|
) {
|
||||||
this.compileClassDeclaration(<ClassDeclaration>statement, []);
|
this.compileClassDeclaration(<ClassDeclaration>statement, [], null);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -514,7 +521,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
// resolve now if annotated
|
// resolve now if annotated
|
||||||
if (declaration.type) {
|
if (declaration.type) {
|
||||||
let resolvedType = this.program.resolveType(declaration.type); // reports
|
let resolvedType = this.resolver.resolveType(declaration.type); // reports
|
||||||
if (!resolvedType) return false;
|
if (!resolvedType) return false;
|
||||||
if (resolvedType == Type.void) {
|
if (resolvedType == Type.void) {
|
||||||
this.error(
|
this.error(
|
||||||
@ -827,7 +834,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
outerScope: Flow | null,
|
outerScope: Flow | null,
|
||||||
reportNode: Node
|
reportNode: Node
|
||||||
): Function | null {
|
): Function | null {
|
||||||
var instance = prototype.resolveUsingTypeArguments( // reports
|
var instance = this.resolver.resolveFunctionInclTypeArguments(
|
||||||
|
prototype,
|
||||||
typeArguments,
|
typeArguments,
|
||||||
contextualTypeArguments,
|
contextualTypeArguments,
|
||||||
reportNode
|
reportNode
|
||||||
@ -1203,8 +1211,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
compileClassDeclaration(
|
compileClassDeclaration(
|
||||||
declaration: ClassDeclaration,
|
declaration: ClassDeclaration,
|
||||||
typeArguments: TypeNode[],
|
typeArguments: TypeNode[],
|
||||||
contextualTypeArguments: Map<string,Type> | null = null,
|
contextualTypeArguments: Map<string,Type> | null = null
|
||||||
alternativeReportNode: Node | null = null
|
|
||||||
): void {
|
): void {
|
||||||
var element = assert(this.program.elementsLookup.get(declaration.fileLevelInternalName));
|
var element = assert(this.program.elementsLookup.get(declaration.fileLevelInternalName));
|
||||||
assert(element.kind == ElementKind.CLASS_PROTOTYPE);
|
assert(element.kind == ElementKind.CLASS_PROTOTYPE);
|
||||||
@ -1212,7 +1219,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
<ClassPrototype>element,
|
<ClassPrototype>element,
|
||||||
typeArguments,
|
typeArguments,
|
||||||
contextualTypeArguments,
|
contextualTypeArguments,
|
||||||
alternativeReportNode
|
declaration
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1222,10 +1229,11 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
contextualTypeArguments: Map<string,Type> | null = null,
|
contextualTypeArguments: Map<string,Type> | null = null,
|
||||||
alternativeReportNode: Node | null = null
|
alternativeReportNode: Node | null = null
|
||||||
): void {
|
): void {
|
||||||
var instance = prototype.resolveUsingTypeArguments( // reports
|
var instance = this.resolver.resolveClassInclTypeArguments(
|
||||||
|
prototype,
|
||||||
typeArguments,
|
typeArguments,
|
||||||
contextualTypeArguments,
|
contextualTypeArguments,
|
||||||
alternativeReportNode
|
alternativeReportNode || prototype.declaration
|
||||||
);
|
);
|
||||||
if (!instance) return;
|
if (!instance) return;
|
||||||
this.compileClass(instance);
|
this.compileClass(instance);
|
||||||
@ -2002,13 +2010,14 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
// other variables become locals
|
// other variables become locals
|
||||||
var initializers = new Array<ExpressionRef>();
|
var initializers = new Array<ExpressionRef>();
|
||||||
var flow = this.currentFunction.flow;
|
var flow = this.currentFunction.flow;
|
||||||
|
var resolver = this.resolver;
|
||||||
for (let i = 0; i < numDeclarations; ++i) {
|
for (let i = 0; i < numDeclarations; ++i) {
|
||||||
let declaration = declarations[i];
|
let declaration = declarations[i];
|
||||||
let name = declaration.name.text;
|
let name = declaration.name.text;
|
||||||
let type: Type | null = null;
|
let type: Type | null = null;
|
||||||
let initExpr: ExpressionRef = 0;
|
let initExpr: ExpressionRef = 0;
|
||||||
if (declaration.type) {
|
if (declaration.type) {
|
||||||
type = program.resolveType( // reports
|
type = resolver.resolveType( // reports
|
||||||
declaration.type,
|
declaration.type,
|
||||||
flow.contextualTypeArguments
|
flow.contextualTypeArguments
|
||||||
);
|
);
|
||||||
@ -2609,7 +2618,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compileAssertionExpression(expression: AssertionExpression, contextualType: Type): ExpressionRef {
|
compileAssertionExpression(expression: AssertionExpression, contextualType: Type): ExpressionRef {
|
||||||
var toType = this.program.resolveType( // reports
|
var toType = this.resolver.resolveType( // reports
|
||||||
expression.toType,
|
expression.toType,
|
||||||
this.currentFunction.flow.contextualTypeArguments
|
this.currentFunction.flow.contextualTypeArguments
|
||||||
);
|
);
|
||||||
@ -3585,7 +3594,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE);
|
assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE);
|
||||||
this.f32PowInstance = instance = (<FunctionPrototype>prototype).resolve();
|
this.f32PowInstance = instance = this.resolver.resolveFunction(<FunctionPrototype>prototype, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Math.pow otherwise (result is f64)
|
// Math.pow otherwise (result is f64)
|
||||||
@ -3627,7 +3636,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE);
|
assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE);
|
||||||
this.f64PowInstance = instance = (<FunctionPrototype>prototype).resolve();
|
this.f64PowInstance = instance = this.resolver.resolveFunction(<FunctionPrototype>prototype, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(instance && this.compileFunction(instance))) {
|
if (!(instance && this.compileFunction(instance))) {
|
||||||
@ -3877,7 +3886,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE);
|
assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE);
|
||||||
this.f32ModInstance = instance = (<FunctionPrototype>prototype).resolve();
|
this.f32ModInstance = instance = this.resolver.resolveFunction(<FunctionPrototype>prototype, null);
|
||||||
}
|
}
|
||||||
if (!(instance && this.compileFunction(instance))) {
|
if (!(instance && this.compileFunction(instance))) {
|
||||||
expr = module.createUnreachable();
|
expr = module.createUnreachable();
|
||||||
@ -3908,7 +3917,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE);
|
assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE);
|
||||||
this.f64ModInstance = instance = (<FunctionPrototype>prototype).resolve();
|
this.f64ModInstance = instance = this.resolver.resolveFunction(<FunctionPrototype>prototype, null);
|
||||||
}
|
}
|
||||||
if (!(instance && this.compileFunction(instance))) {
|
if (!(instance && this.compileFunction(instance))) {
|
||||||
expr = module.createUnreachable();
|
expr = module.createUnreachable();
|
||||||
@ -4577,8 +4586,9 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
compileAssignment(expression: Expression, valueExpression: Expression, contextualType: Type): ExpressionRef {
|
compileAssignment(expression: Expression, valueExpression: Expression, contextualType: Type): ExpressionRef {
|
||||||
var program = this.program;
|
var program = this.program;
|
||||||
|
var resolver = program.resolver;
|
||||||
var currentFunction = this.currentFunction;
|
var currentFunction = this.currentFunction;
|
||||||
var target = program.resolveExpression(expression, currentFunction); // reports
|
var target = resolver.resolveExpression(expression, currentFunction); // reports
|
||||||
if (!target) return this.module.createUnreachable();
|
if (!target) return this.module.createUnreachable();
|
||||||
|
|
||||||
// to compile just the value, we need to know the target's type
|
// to compile just the value, we need to know the target's type
|
||||||
@ -4597,9 +4607,9 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ElementKind.PROPERTY: {
|
case ElementKind.PROPERTY: {
|
||||||
let prototype = (<Property>target).setterPrototype;
|
let setterPrototype = (<Property>target).setterPrototype;
|
||||||
if (prototype) {
|
if (setterPrototype) {
|
||||||
let instance = prototype.resolve(); // reports
|
let instance = this.resolver.resolveFunction(setterPrototype, null);
|
||||||
if (!instance) return this.module.createUnreachable();
|
if (!instance) return this.module.createUnreachable();
|
||||||
assert(instance.signature.parameterTypes.length == 1); // parser must guarantee this
|
assert(instance.signature.parameterTypes.length == 1); // parser must guarantee this
|
||||||
targetType = instance.signature.parameterTypes[0];
|
targetType = instance.signature.parameterTypes[0];
|
||||||
@ -4612,7 +4622,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return this.module.createUnreachable();
|
return this.module.createUnreachable();
|
||||||
}
|
}
|
||||||
case ElementKind.CLASS: {
|
case ElementKind.CLASS: {
|
||||||
if (program.resolvedElementExpression) { // indexed access
|
if (resolver.resolvedElementExpression) { // indexed access
|
||||||
let isUnchecked = currentFunction.flow.is(FlowFlags.UNCHECKED_CONTEXT);
|
let isUnchecked = currentFunction.flow.is(FlowFlags.UNCHECKED_CONTEXT);
|
||||||
let indexedSet = (<Class>target).lookupOverload(OperatorKind.INDEXED_SET, isUnchecked);
|
let indexedSet = (<Class>target).lookupOverload(OperatorKind.INDEXED_SET, isUnchecked);
|
||||||
if (!indexedSet) {
|
if (!indexedSet) {
|
||||||
@ -4661,7 +4671,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
tee: bool = false
|
tee: bool = false
|
||||||
): ExpressionRef {
|
): ExpressionRef {
|
||||||
var module = this.module;
|
var module = this.module;
|
||||||
var target = this.program.resolveExpression(expression, this.currentFunction); // reports
|
var target = this.resolver.resolveExpression(expression, this.currentFunction); // reports
|
||||||
if (!target) return module.createUnreachable();
|
if (!target) return module.createUnreachable();
|
||||||
|
|
||||||
switch (target.kind) {
|
switch (target.kind) {
|
||||||
@ -4725,7 +4735,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
);
|
);
|
||||||
return module.createUnreachable();
|
return module.createUnreachable();
|
||||||
}
|
}
|
||||||
let thisExpression = assert(this.program.resolvedThisExpression);
|
let thisExpression = assert(this.resolver.resolvedThisExpression);
|
||||||
let thisExpr = this.compileExpressionRetainType(
|
let thisExpr = this.compileExpressionRetainType(
|
||||||
thisExpression,
|
thisExpression,
|
||||||
this.options.usizeType,
|
this.options.usizeType,
|
||||||
@ -4771,13 +4781,13 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case ElementKind.PROPERTY: {
|
case ElementKind.PROPERTY: {
|
||||||
let setterPrototype = (<Property>target).setterPrototype;
|
let setterPrototype = (<Property>target).setterPrototype;
|
||||||
if (setterPrototype) {
|
if (setterPrototype) {
|
||||||
let setterInstance = setterPrototype.resolve(); // reports
|
let setterInstance = this.resolver.resolveFunction(setterPrototype, null);
|
||||||
if (!setterInstance) return module.createUnreachable();
|
if (!setterInstance) return module.createUnreachable();
|
||||||
|
|
||||||
// call just the setter if the return value isn't of interest
|
// call just the setter if the return value isn't of interest
|
||||||
if (!tee) {
|
if (!tee) {
|
||||||
if (setterInstance.is(CommonFlags.INSTANCE)) {
|
if (setterInstance.is(CommonFlags.INSTANCE)) {
|
||||||
let thisExpression = assert(this.program.resolvedThisExpression);
|
let thisExpression = assert(this.resolver.resolvedThisExpression);
|
||||||
let thisExpr = this.compileExpressionRetainType(
|
let thisExpr = this.compileExpressionRetainType(
|
||||||
thisExpression,
|
thisExpression,
|
||||||
this.options.usizeType,
|
this.options.usizeType,
|
||||||
@ -4792,12 +4802,12 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
// otherwise call the setter first, then the getter
|
// otherwise call the setter first, then the getter
|
||||||
let getterPrototype = (<Property>target).getterPrototype;
|
let getterPrototype = (<Property>target).getterPrototype;
|
||||||
assert(getterPrototype != null); // must have one if there is a setter
|
assert(getterPrototype != null); // must have one if there is a setter
|
||||||
let getterInstance = (<FunctionPrototype>getterPrototype).resolve(); // reports
|
let getterInstance = this.resolver.resolveFunction(<FunctionPrototype>getterPrototype, null);
|
||||||
if (!getterInstance) return module.createUnreachable();
|
if (!getterInstance) return module.createUnreachable();
|
||||||
let returnType = getterInstance.signature.returnType;
|
let returnType = getterInstance.signature.returnType;
|
||||||
let nativeReturnType = returnType.toNativeType();
|
let nativeReturnType = returnType.toNativeType();
|
||||||
if (setterInstance.is(CommonFlags.INSTANCE)) {
|
if (setterInstance.is(CommonFlags.INSTANCE)) {
|
||||||
let thisExpression = assert(this.program.resolvedThisExpression);
|
let thisExpression = assert(this.resolver.resolvedThisExpression);
|
||||||
let thisExpr = this.compileExpressionRetainType(
|
let thisExpr = this.compileExpressionRetainType(
|
||||||
thisExpression,
|
thisExpression,
|
||||||
this.options.usizeType,
|
this.options.usizeType,
|
||||||
@ -4830,7 +4840,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return module.createUnreachable();
|
return module.createUnreachable();
|
||||||
}
|
}
|
||||||
case ElementKind.CLASS: {
|
case ElementKind.CLASS: {
|
||||||
let elementExpression = this.program.resolvedElementExpression;
|
let elementExpression = this.resolver.resolvedElementExpression;
|
||||||
if (elementExpression) {
|
if (elementExpression) {
|
||||||
let isUnchecked = this.currentFunction.flow.is(FlowFlags.UNCHECKED_CONTEXT);
|
let isUnchecked = this.currentFunction.flow.is(FlowFlags.UNCHECKED_CONTEXT);
|
||||||
let indexedGet = (<Class>target).lookupOverload(OperatorKind.INDEXED_GET, isUnchecked);
|
let indexedGet = (<Class>target).lookupOverload(OperatorKind.INDEXED_GET, isUnchecked);
|
||||||
@ -4851,7 +4861,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return module.createUnreachable();
|
return module.createUnreachable();
|
||||||
}
|
}
|
||||||
let targetType = (<Class>target).type;
|
let targetType = (<Class>target).type;
|
||||||
let thisExpression = assert(this.program.resolvedThisExpression);
|
let thisExpression = assert(this.resolver.resolvedThisExpression);
|
||||||
let thisExpr = this.compileExpressionRetainType(
|
let thisExpr = this.compileExpressionRetainType(
|
||||||
thisExpression,
|
thisExpression,
|
||||||
this.options.usizeType,
|
this.options.usizeType,
|
||||||
@ -4901,7 +4911,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
compileCallExpression(expression: CallExpression, contextualType: Type): ExpressionRef {
|
compileCallExpression(expression: CallExpression, contextualType: Type): ExpressionRef {
|
||||||
var module = this.module;
|
var module = this.module;
|
||||||
var currentFunction = this.currentFunction;
|
var currentFunction = this.currentFunction;
|
||||||
var target = this.program.resolveExpression(expression.expression, currentFunction); // reports
|
var target = this.resolver.resolveExpression(expression.expression, currentFunction); // reports
|
||||||
if (!target) return module.createUnreachable();
|
if (!target) return module.createUnreachable();
|
||||||
|
|
||||||
var signature: Signature | null;
|
var signature: Signature | null;
|
||||||
@ -4929,7 +4939,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
);
|
);
|
||||||
return module.createUnreachable();
|
return module.createUnreachable();
|
||||||
}
|
}
|
||||||
instance = prototype.resolveUsingTypeArguments( // reports
|
instance = this.resolver.resolveFunctionInclTypeArguments(
|
||||||
|
prototype,
|
||||||
typeArguments,
|
typeArguments,
|
||||||
this.currentFunction.flow.contextualTypeArguments,
|
this.currentFunction.flow.contextualTypeArguments,
|
||||||
expression
|
expression
|
||||||
@ -4984,10 +4995,9 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
inferredTypes.set(name, inferredType);
|
inferredTypes.set(name, inferredType);
|
||||||
} else {
|
} else {
|
||||||
let concreteType = this.program.resolveType(
|
let concreteType = this.resolver.resolveType(
|
||||||
parameterTypes[i].type,
|
parameterTypes[i].type,
|
||||||
this.currentFunction.flow.contextualTypeArguments,
|
this.currentFunction.flow.contextualTypeArguments
|
||||||
true
|
|
||||||
);
|
);
|
||||||
if (!concreteType) return module.createUnreachable();
|
if (!concreteType) return module.createUnreachable();
|
||||||
argumentExprs[i] = this.compileExpression(
|
argumentExprs[i] = this.compileExpression(
|
||||||
@ -5003,7 +5013,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
let inferredType = assert(inferredTypes.get(typeParameters[i].name.text)); // TODO
|
let inferredType = assert(inferredTypes.get(typeParameters[i].name.text)); // TODO
|
||||||
resolvedTypeArguments[i] = inferredType;
|
resolvedTypeArguments[i] = inferredType;
|
||||||
}
|
}
|
||||||
instance = prototype.resolve(
|
instance = this.resolver.resolveFunction(
|
||||||
|
prototype,
|
||||||
resolvedTypeArguments,
|
resolvedTypeArguments,
|
||||||
this.currentFunction.flow.contextualTypeArguments
|
this.currentFunction.flow.contextualTypeArguments
|
||||||
);
|
);
|
||||||
@ -5015,7 +5026,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
// otherwise resolve the non-generic call as usual
|
// otherwise resolve the non-generic call as usual
|
||||||
} else {
|
} else {
|
||||||
instance = prototype.resolve(
|
instance = this.resolver.resolveFunction(
|
||||||
|
prototype,
|
||||||
null,
|
null,
|
||||||
this.currentFunction.flow.contextualTypeArguments
|
this.currentFunction.flow.contextualTypeArguments
|
||||||
);
|
);
|
||||||
@ -5026,7 +5038,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
let thisExpr: ExpressionRef = 0;
|
let thisExpr: ExpressionRef = 0;
|
||||||
if (instance.is(CommonFlags.INSTANCE)) {
|
if (instance.is(CommonFlags.INSTANCE)) {
|
||||||
thisExpr = this.compileExpressionRetainType(
|
thisExpr = this.compileExpressionRetainType(
|
||||||
assert(this.program.resolvedThisExpression),
|
assert(this.resolver.resolvedThisExpression),
|
||||||
this.options.usizeType,
|
this.options.usizeType,
|
||||||
WrapMode.NONE
|
WrapMode.NONE
|
||||||
);
|
);
|
||||||
@ -5069,7 +5081,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case ElementKind.FIELD: {
|
case ElementKind.FIELD: {
|
||||||
let type = (<Field>target).type;
|
let type = (<Field>target).type;
|
||||||
if (signature = type.signatureReference) {
|
if (signature = type.signatureReference) {
|
||||||
let thisExpression = assert(this.program.resolvedThisExpression);
|
let thisExpression = assert(this.resolver.resolvedThisExpression);
|
||||||
let thisExpr = this.compileExpressionRetainType(
|
let thisExpr = this.compileExpressionRetainType(
|
||||||
thisExpression,
|
thisExpression,
|
||||||
this.options.usizeType,
|
this.options.usizeType,
|
||||||
@ -5125,13 +5137,31 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
expression: CallExpression,
|
expression: CallExpression,
|
||||||
contextualType: Type
|
contextualType: Type
|
||||||
): ExpressionRef {
|
): ExpressionRef {
|
||||||
var expr = compileBuiltinCall( // reports
|
var typeArguments: Type[] | null = null;
|
||||||
|
|
||||||
|
// builtins handle omitted type arguments on their own. if present, however, resolve them here
|
||||||
|
// and pass them to the builtin, even if it's still up to the builtin how to handle them.
|
||||||
|
var typeArgumentNodes = expression.typeArguments;
|
||||||
|
if (expression.typeArguments) {
|
||||||
|
if (!prototype.is(CommonFlags.GENERIC)) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Type_0_is_not_generic,
|
||||||
|
expression.range, prototype.internalName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
typeArguments = this.resolver.resolveTypeArguments(
|
||||||
|
assert(prototype.declaration.typeParameters),
|
||||||
|
typeArgumentNodes,
|
||||||
|
this.currentFunction.flow.contextualTypeArguments,
|
||||||
|
expression
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now compile the builtin, which usually returns a block of code that replaces the call.
|
||||||
|
var expr = compileBuiltinCall(
|
||||||
this,
|
this,
|
||||||
prototype,
|
prototype,
|
||||||
prototype.resolveBuiltinTypeArguments(
|
typeArguments,
|
||||||
expression.typeArguments,
|
|
||||||
this.currentFunction.flow.contextualTypeArguments
|
|
||||||
),
|
|
||||||
expression.arguments,
|
expression.arguments,
|
||||||
contextualType,
|
contextualType,
|
||||||
expression
|
expression
|
||||||
@ -5733,7 +5763,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compileElementAccessExpression(expression: ElementAccessExpression, contextualType: Type): ExpressionRef {
|
compileElementAccessExpression(expression: ElementAccessExpression, contextualType: Type): ExpressionRef {
|
||||||
var target = this.program.resolveElementAccess(expression, this.currentFunction); // reports
|
var target = this.resolver.resolveElementAccess(expression, this.currentFunction); // reports
|
||||||
if (!target) return this.module.createUnreachable();
|
if (!target) return this.module.createUnreachable();
|
||||||
switch (target.kind) {
|
switch (target.kind) {
|
||||||
case ElementKind.CLASS: {
|
case ElementKind.CLASS: {
|
||||||
@ -5895,7 +5925,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// otherwise resolve
|
// otherwise resolve
|
||||||
var target = this.program.resolveIdentifier( // reports
|
var target = this.resolver.resolveIdentifier( // reports
|
||||||
expression,
|
expression,
|
||||||
this.currentEnum || currentFunction
|
this.currentEnum || currentFunction
|
||||||
);
|
);
|
||||||
@ -5940,7 +5970,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return this.module.createGetGlobal((<EnumValue>target).internalName, NativeType.I32);
|
return this.module.createGetGlobal((<EnumValue>target).internalName, NativeType.I32);
|
||||||
}
|
}
|
||||||
case ElementKind.FUNCTION_PROTOTYPE: {
|
case ElementKind.FUNCTION_PROTOTYPE: {
|
||||||
let instance = (<FunctionPrototype>target).resolve(
|
let instance = this.resolver.resolveFunction(
|
||||||
|
<FunctionPrototype>target,
|
||||||
null,
|
null,
|
||||||
currentFunction.flow.contextualTypeArguments
|
currentFunction.flow.contextualTypeArguments
|
||||||
);
|
);
|
||||||
@ -5967,7 +5998,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
// possible in AS anyway.
|
// possible in AS anyway.
|
||||||
var expr = this.compileExpressionRetainType(expression.expression, this.options.usizeType, WrapMode.NONE);
|
var expr = this.compileExpressionRetainType(expression.expression, this.options.usizeType, WrapMode.NONE);
|
||||||
var type = this.currentType;
|
var type = this.currentType;
|
||||||
var isType = this.program.resolveType(expression.isType);
|
var isType = this.resolver.resolveType(expression.isType);
|
||||||
this.currentType = Type.bool;
|
this.currentType = Type.bool;
|
||||||
if (!isType) return module.createUnreachable();
|
if (!isType) return module.createUnreachable();
|
||||||
return type.is(TypeFlags.NULLABLE) && !isType.is(TypeFlags.NULLABLE)
|
return type.is(TypeFlags.NULLABLE) && !isType.is(TypeFlags.NULLABLE)
|
||||||
@ -6161,7 +6192,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
// obtain the array type
|
// obtain the array type
|
||||||
var arrayPrototype = assert(this.program.arrayPrototype);
|
var arrayPrototype = assert(this.program.arrayPrototype);
|
||||||
if (!arrayPrototype || arrayPrototype.kind != ElementKind.CLASS_PROTOTYPE) return module.createUnreachable();
|
if (!arrayPrototype || arrayPrototype.kind != ElementKind.CLASS_PROTOTYPE) return module.createUnreachable();
|
||||||
var arrayInstance = (<ClassPrototype>arrayPrototype).resolve([ elementType ]);
|
var arrayInstance = this.resolver.resolveClass(<ClassPrototype>arrayPrototype, [ elementType ]);
|
||||||
if (!arrayInstance) return module.createUnreachable();
|
if (!arrayInstance) return module.createUnreachable();
|
||||||
var arrayType = arrayInstance.type;
|
var arrayType = arrayInstance.type;
|
||||||
|
|
||||||
@ -6367,7 +6398,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
var currentFunction = this.currentFunction;
|
var currentFunction = this.currentFunction;
|
||||||
|
|
||||||
// obtain the class being instantiated
|
// obtain the class being instantiated
|
||||||
var target = this.program.resolveExpression( // reports
|
var target = this.resolver.resolveExpression( // reports
|
||||||
expression.expression,
|
expression.expression,
|
||||||
currentFunction
|
currentFunction
|
||||||
);
|
);
|
||||||
@ -6388,12 +6419,14 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
(classReference = contextualType.classReference) !== null &&
|
(classReference = contextualType.classReference) !== null &&
|
||||||
classReference.is(CommonFlags.GENERIC)
|
classReference.is(CommonFlags.GENERIC)
|
||||||
) {
|
) {
|
||||||
classInstance = classPrototype.resolve(
|
classInstance = this.resolver.resolveClass(
|
||||||
|
classPrototype,
|
||||||
classReference.typeArguments,
|
classReference.typeArguments,
|
||||||
currentFunction.flow.contextualTypeArguments
|
currentFunction.flow.contextualTypeArguments
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
classInstance = classPrototype.resolveUsingTypeArguments( // reports
|
classInstance = this.resolver.resolveClassInclTypeArguments(
|
||||||
|
classPrototype,
|
||||||
typeArguments,
|
typeArguments,
|
||||||
currentFunction.flow.contextualTypeArguments,
|
currentFunction.flow.contextualTypeArguments,
|
||||||
expression
|
expression
|
||||||
@ -6448,10 +6481,9 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
contextualType: Type,
|
contextualType: Type,
|
||||||
retainConstantType: bool
|
retainConstantType: bool
|
||||||
): ExpressionRef {
|
): ExpressionRef {
|
||||||
var program = this.program;
|
|
||||||
var module = this.module;
|
var module = this.module;
|
||||||
|
|
||||||
var target = program.resolvePropertyAccess(propertyAccess, this.currentFunction); // reports
|
var target = this.resolver.resolvePropertyAccess(propertyAccess, this.currentFunction); // reports
|
||||||
if (!target) return module.createUnreachable();
|
if (!target) return module.createUnreachable();
|
||||||
|
|
||||||
switch (target.kind) {
|
switch (target.kind) {
|
||||||
@ -6480,7 +6512,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return module.createGetGlobal((<EnumValue>target).internalName, NativeType.I32);
|
return module.createGetGlobal((<EnumValue>target).internalName, NativeType.I32);
|
||||||
}
|
}
|
||||||
case ElementKind.FIELD: { // instance field
|
case ElementKind.FIELD: { // instance field
|
||||||
let thisExpression = assert(program.resolvedThisExpression);
|
let thisExpression = assert(this.resolver.resolvedThisExpression);
|
||||||
assert((<Field>target).memoryOffset >= 0);
|
assert((<Field>target).memoryOffset >= 0);
|
||||||
let thisExpr = this.compileExpressionRetainType(
|
let thisExpr = this.compileExpressionRetainType(
|
||||||
thisExpression,
|
thisExpression,
|
||||||
@ -6499,7 +6531,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
case ElementKind.PROPERTY: { // instance property (here: getter)
|
case ElementKind.PROPERTY: { // instance property (here: getter)
|
||||||
let prototype = (<Property>target).getterPrototype;
|
let prototype = (<Property>target).getterPrototype;
|
||||||
if (prototype) {
|
if (prototype) {
|
||||||
let instance = prototype.resolve(null); // reports
|
let instance = this.resolver.resolveFunction(prototype, null);
|
||||||
if (!instance) return module.createUnreachable();
|
if (!instance) return module.createUnreachable();
|
||||||
let signature = instance.signature;
|
let signature = instance.signature;
|
||||||
if (!this.checkCallSignature( // reports
|
if (!this.checkCallSignature( // reports
|
||||||
@ -6514,7 +6546,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
if (instance.is(CommonFlags.INSTANCE)) {
|
if (instance.is(CommonFlags.INSTANCE)) {
|
||||||
let parent = assert(instance.parent);
|
let parent = assert(instance.parent);
|
||||||
assert(parent.kind == ElementKind.CLASS);
|
assert(parent.kind == ElementKind.CLASS);
|
||||||
let thisExpression = assert(program.resolvedThisExpression);
|
let thisExpression = assert(this.resolver.resolvedThisExpression);
|
||||||
let thisExpr = this.compileExpressionRetainType(
|
let thisExpr = this.compileExpressionRetainType(
|
||||||
thisExpression,
|
thisExpression,
|
||||||
this.options.usizeType,
|
this.options.usizeType,
|
||||||
|
1062
src/program.ts
1062
src/program.ts
File diff suppressed because it is too large
Load Diff
1168
src/resolver.ts
Normal file
1168
src/resolver.ts
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user