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:
dcodeIO 2018-07-13 00:22:22 +02:00
parent 585d246165
commit cd14b296ce
6 changed files with 1314 additions and 1064 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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

View File

@ -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,

File diff suppressed because it is too large Load Diff

1168
src/resolver.ts Normal file

File diff suppressed because it is too large Load Diff