Skip to content

Commit 62071b7

Browse files
authored
fix: Fix type and local confusion when resolving types (#2075)
1 parent 880b2d5 commit 62071b7

8 files changed

+156
-110
lines changed

src/builtins.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9540,7 +9540,7 @@ function ensureVisitMembersOf(compiler: Compiler, instance: Class): void {
95409540
// for example to visit all members of a collection, e.g. arrays and maps.
95419541
var hasVisitImpl = false;
95429542
if (instance.isDeclaredInLibrary) {
9543-
let visitPrototype = instance.lookupInSelf("__visit");
9543+
let visitPrototype = instance.getMember("__visit");
95449544
if (visitPrototype) {
95459545
assert(visitPrototype.kind == ElementKind.FUNCTION_PROTOTYPE);
95469546
let visitInstance = program.resolver.resolveFunction(<FunctionPrototype>visitPrototype, null);

src/compiler.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ import {
8888
PropertyPrototype,
8989
IndexSignature,
9090
File,
91-
mangleInternalName,
92-
DeclaredElement
91+
mangleInternalName
9392
} from "./program";
9493

9594
import {
@@ -8428,7 +8427,7 @@ export class Compiler extends DiagnosticEmitter {
84288427
)
84298428
);
84308429
// tempData = tempThis.dataStart
8431-
var dataStartMember = assert(arrayInstance.lookupInSelf("dataStart"));
8430+
var dataStartMember = assert(arrayInstance.getMember("dataStart"));
84328431
assert(dataStartMember.kind == ElementKind.FIELD);
84338432
stmts.push(
84348433
module.local_set(tempDataStart.index,
@@ -8677,8 +8676,8 @@ export class Compiler extends DiagnosticEmitter {
86778676
// Iterate through the members defined in our expression
86788677
for (let i = 0; i < numNames; ++i) {
86798678
let memberName = names[i].text;
8680-
let member: DeclaredElement;
8681-
if (!members || !members.has(memberName) || (member = assert(members.get(memberName))).kind != ElementKind.FIELD) {
8679+
let member = classReference.getMember(memberName);
8680+
if (!member || member.kind != ElementKind.FIELD) {
86828681
this.error(
86838682
DiagnosticCode.Property_0_does_not_exist_on_type_1,
86848683
names[i].range, memberName, classType.toString()

src/program.ts

+42-93
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ export class Program extends DiagnosticEmitter {
12231223
);
12241224
}
12251225
} else { // i.e. export { foo [as bar] }
1226-
let element = file.lookupInSelf(localName);
1226+
let element = file.getMember(localName);
12271227
if (element) {
12281228
file.ensureExport(exportName, element);
12291229
} else {
@@ -1751,7 +1751,7 @@ export class Program extends DiagnosticEmitter {
17511751
}
17521752

17531753
// exported from this file
1754-
element = foreignFile.lookupInSelf(queuedExport.localIdentifier.text);
1754+
element = foreignFile.getMember(queuedExport.localIdentifier.text);
17551755
if (element) return element;
17561756
}
17571757
}
@@ -2200,7 +2200,7 @@ export class Program extends DiagnosticEmitter {
22002200
if (foreignPath === null) {
22012201

22022202
// resolve right away if the local element already exists
2203-
if (element = localFile.lookupInSelf(localName)) {
2203+
if (element = localFile.getMember(localName)) {
22042204
localFile.ensureExport(foreignName, element);
22052205

22062206
// otherwise queue it
@@ -2514,7 +2514,7 @@ export class Program extends DiagnosticEmitter {
25142514
this.checkDecorators(declaration.decorators, DecoratorFlags.GLOBAL)
25152515
);
25162516
if (!parent.add(name, original)) return null;
2517-
var element = assert(parent.lookupInSelf(name)); // possibly merged
2517+
var element = assert(parent.getMember(name)); // possibly merged
25182518
var members = declaration.members;
25192519
for (let i = 0, k = members.length; i < k; ++i) {
25202520
let member = members[i];
@@ -2775,15 +2775,17 @@ export abstract class Element {
27752775
/** Tests if this element has a specific decorator flag or flags. */
27762776
hasDecorator(flag: DecoratorFlags): bool { return (this.decoratorFlags & flag) == flag; }
27772777

2778-
/** Looks up the element with the specified name within this element. */
2779-
lookupInSelf(name: string): DeclaredElement | null {
2778+
/** Get the member with the specified name, if any. */
2779+
getMember(name: string): DeclaredElement | null {
27802780
var members = this.members;
2781-
if (members !== null && members.has(name)) return assert(members.get(name));
2781+
if (members && members.has(name)) return assert(members.get(name));
27822782
return null;
27832783
}
27842784

2785-
/** Looks up the element with the specified name relative to this element, like in JS. */
2786-
abstract lookup(name: string): Element | null;
2785+
/** Looks up the element with the specified name relative to this element. */
2786+
lookup(name: string, isType: bool = false): Element | null {
2787+
return this.parent.lookup(name, isType);
2788+
}
27872789

27882790
/** Adds an element as a member of this one. Reports and returns `false` if a duplicate. */
27892791
add(name: string, element: DeclaredElement, localIdentifierIfImport: IdentifierExpression | null = null): bool {
@@ -3038,7 +3040,7 @@ export class File extends Element {
30383040
element = this.program.ensureGlobal(name, element); // possibly merged globally
30393041
}
30403042
if (!super.add(name, element, localIdentifierIfImport)) return false;
3041-
element = assert(this.lookupInSelf(name)); // possibly merged locally
3043+
element = assert(this.getMember(name)); // possibly merged locally
30423044
if (element.is(CommonFlags.EXPORT) && !localIdentifierIfImport) {
30433045
this.ensureExport(
30443046
element.name,
@@ -3049,23 +3051,23 @@ export class File extends Element {
30493051
}
30503052

30513053
/* @override */
3052-
lookupInSelf(name: string): DeclaredElement | null {
3053-
var element = super.lookupInSelf(name);
3054+
getMember(name: string): DeclaredElement | null {
3055+
var element = super.getMember(name);
30543056
if (element) return element;
30553057
var exportsStar = this.exportsStar;
30563058
if (exportsStar) {
30573059
for (let i = 0, k = exportsStar.length; i < k; ++i) {
3058-
if (element = exportsStar[i].lookupInSelf(name)) return element;
3060+
if (element = exportsStar[i].getMember(name)) return element;
30593061
}
30603062
}
30613063
return null;
30623064
}
30633065

30643066
/* @override */
3065-
lookup(name: string): Element | null {
3066-
var element = this.lookupInSelf(name);
3067+
lookup(name: string, isType: bool = false): Element | null {
3068+
var element = this.getMember(name);
30673069
if (element) return element;
3068-
return this.program.lookup(name);
3070+
return this.program.lookup(name); // has no meaningful parent
30693071
}
30703072

30713073
/** Ensures that an element is an export of this file. */
@@ -3176,11 +3178,6 @@ export class TypeDefinition extends TypedElement {
31763178
get typeNode(): TypeNode {
31773179
return (<TypeDeclaration>this.declaration).type;
31783180
}
3179-
3180-
/* @override */
3181-
lookup(name: string): Element | null {
3182-
return this.parent.lookup(name);
3183-
}
31843181
}
31853182

31863183
/** A namespace that differs from a file in being user-declared with a name. */
@@ -3209,10 +3206,10 @@ export class Namespace extends DeclaredElement {
32093206
}
32103207

32113208
/* @override */
3212-
lookup(name: string): Element | null {
3213-
var inSelf = this.lookupInSelf(name);
3214-
if (inSelf) return inSelf;
3215-
return this.parent.lookup(name);
3209+
lookup(name: string, isType: bool = false): Element | null {
3210+
var member = this.getMember(name);
3211+
if (member) return member;
3212+
return super.lookup(name, isType);
32163213
}
32173214
}
32183215

@@ -3243,10 +3240,10 @@ export class Enum extends TypedElement {
32433240
}
32443241

32453242
/* @override */
3246-
lookup(name: string): Element | null {
3247-
var inSelf = this.lookupInSelf(name);
3248-
if (inSelf) return inSelf;
3249-
return this.parent.lookup(name);
3243+
lookup(name: string, isType: bool = false): Element | null {
3244+
var member = this.getMember(name);
3245+
if (member) return member;
3246+
return super.lookup(name, isType);
32503247
}
32513248
}
32523249

@@ -3319,11 +3316,6 @@ export abstract class VariableLikeElement extends TypedElement {
33193316
this.constantFloatValue = value;
33203317
this.set(CommonFlags.CONST | CommonFlags.INLINED | CommonFlags.RESOLVED);
33213318
}
3322-
3323-
/** @override */
3324-
lookup(name: string): Element | null {
3325-
return this.parent.lookup(name);
3326-
}
33273319
}
33283320

33293321
/** An enum value. */
@@ -3357,11 +3349,6 @@ export class EnumValue extends VariableLikeElement {
33573349
get valueNode(): Expression | null {
33583350
return (<EnumValueDeclaration>this.declaration).initializer;
33593351
}
3360-
3361-
/* @override */
3362-
lookup(name: string): Element | null {
3363-
return this.parent.lookup(name);
3364-
}
33653352
}
33663353

33673354
/** A global variable. */
@@ -3546,11 +3533,6 @@ export class FunctionPrototype extends DeclaredElement {
35463533
else assert(!instances.has(instanceKey));
35473534
instances.set(instanceKey, instance);
35483535
}
3549-
3550-
/* @override */
3551-
lookup(name: string): Element | null {
3552-
return this.parent.lookup(name);
3553-
}
35543536
}
35553537

35563538
/** A resolved function. */
@@ -3709,10 +3691,12 @@ export class Function extends TypedElement {
37093691
}
37103692

37113693
/* @override */
3712-
lookup(name: string): Element | null {
3713-
var locals = this.localsByName;
3714-
if (locals.has(name)) return assert(locals.get(name));
3715-
return this.parent.lookup(name);
3694+
lookup(name: string, isType: bool = false): Element | null {
3695+
if (!isType) {
3696+
let locals = this.localsByName;
3697+
if (locals.has(name)) return assert(locals.get(name));
3698+
}
3699+
return super.lookup(name, isType);
37163700
}
37173701

37183702
// used by flows to keep track of temporary locals
@@ -3797,11 +3781,6 @@ export class FieldPrototype extends DeclaredElement {
37973781
get parameterIndex(): i32 {
37983782
return (<FieldDeclaration>this.declaration).parameterIndex;
37993783
}
3800-
3801-
/* @override */
3802-
lookup(name: string): Element | null {
3803-
return this.parent.lookup(name);
3804-
}
38053784
}
38063785

38073786
/** A resolved instance field. */
@@ -3912,11 +3891,6 @@ export class PropertyPrototype extends DeclaredElement {
39123891
this.flags &= ~(CommonFlags.GET | CommonFlags.SET);
39133892
}
39143893

3915-
/* @override */
3916-
lookup(name: string): Element | null {
3917-
return this.parent.lookup(name);
3918-
}
3919-
39203894
/** Tests if this prototype is bound to a class. */
39213895
get isBound(): bool {
39223896
switch (this.parent.kind) {
@@ -3992,11 +3966,6 @@ export class Property extends VariableLikeElement {
39923966
registerConcreteElement(this.program, this);
39933967
}
39943968
}
3995-
3996-
/* @override */
3997-
lookup(name: string): Element | null {
3998-
return this.parent.lookup(name);
3999-
}
40003969
}
40013970

40023971
/** A resolved index signature. */
@@ -4026,11 +3995,6 @@ export class IndexSignature extends TypedElement {
40263995
getSetterInstance(isUnchecked: bool): Function | null {
40273996
return (<Class>this.parent).lookupOverload(OperatorKind.INDEXED_SET, isUnchecked);
40283997
}
4029-
4030-
/* @override */
4031-
lookup(name: string): Element | null {
4032-
return this.parent.lookup(name);
4033-
}
40343998
}
40353999

40364000
/** A yet unresolved class prototype. */
@@ -4155,11 +4119,6 @@ export class ClassPrototype extends DeclaredElement {
41554119
else assert(!instances.has(instanceKey));
41564120
instances.set(instanceKey, instance);
41574121
}
4158-
4159-
/* @override */
4160-
lookup(name: string): Element | null {
4161-
return this.parent.lookup(name);
4162-
}
41634122
}
41644123

41654124
/** A resolved class. */
@@ -4211,7 +4170,7 @@ export class Class extends TypedElement {
42114170
/** Tests if this class is array-like. */
42124171
get isArrayLike(): bool {
42134172
if (this.isBuiltinArray) return true;
4214-
var lengthField = this.lookupInSelf("length");
4173+
var lengthField = this.getMember("length");
42154174
return lengthField !== null && (
42164175
lengthField.kind == ElementKind.FIELD ||
42174176
(
@@ -4361,30 +4320,20 @@ export class Class extends TypedElement {
43614320
return null;
43624321
}
43634322

4364-
/* @override */
4365-
lookup(name: string): Element | null {
4366-
return this.parent.lookup(name);
4367-
}
4368-
43694323
/** Gets the method of the specified name, resolved with the given type arguments. */
43704324
getMethod(name: string, typeArguments: Type[] | null = null): Function | null {
4371-
var members = this.members;
4372-
if (members !== null && members.has(name)) {
4373-
let bound = changetype<Element>(members.get(name));
4374-
if (bound.kind == ElementKind.FUNCTION_PROTOTYPE) {
4375-
return this.program.resolver.resolveFunction(<FunctionPrototype>bound, typeArguments);
4376-
}
4325+
var member = this.getMember(name);
4326+
if (member && member.kind == ElementKind.FUNCTION_PROTOTYPE) {
4327+
return this.program.resolver.resolveFunction(<FunctionPrototype>member, typeArguments);
43774328
}
43784329
return null;
43794330
}
43804331

43814332
/** Calculates the memory offset of the specified field. */
43824333
offsetof(fieldName: string): u32 {
4383-
var members = assert(this.members);
4384-
assert(members.has(fieldName));
4385-
var field = <Element>members.get(fieldName);
4386-
assert(field.kind == ElementKind.FIELD);
4387-
return (<Field>field).memoryOffset;
4334+
var member = assert(this.getMember(fieldName));
4335+
assert(member.kind == ElementKind.FIELD);
4336+
return (<Field>member).memoryOffset;
43884337
}
43894338

43904339
/** Creates a buffer suitable to hold a runtime instance of this class. */
@@ -4404,9 +4353,9 @@ export class Class extends TypedElement {
44044353

44054354
/** Writes a field value to a buffer and returns the number of bytes written. */
44064355
writeField<T>(name: string, value: T, buffer: Uint8Array, baseOffset: i32 = this.program.totalOverhead): i32 {
4407-
var element = this.lookupInSelf(name);
4408-
if (element !== null && element.kind == ElementKind.FIELD) {
4409-
let fieldInstance = <Field>element;
4356+
var member = this.getMember(name);
4357+
if (member !== null && member.kind == ElementKind.FIELD) {
4358+
let fieldInstance = <Field>member;
44104359
let offset = baseOffset + fieldInstance.memoryOffset;
44114360
let typeKind = fieldInstance.type.kind;
44124361
switch (typeKind) {

0 commit comments

Comments
 (0)