gofront 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -111,8 +111,16 @@ export const expressionCheckMethods = {
111
111
  if (expr.expr._isTypeRef) {
112
112
  let base = baseType.kind === "named" ? baseType.underlying : baseType;
113
113
  base = this.resolveType(base);
114
+ let methodType = null;
114
115
  if (base?.kind === "struct" && base.methods?.has(expr.field)) {
115
- const methodType = base.methods.get(expr.field);
116
+ methodType = base.methods.get(expr.field);
117
+ } else if (
118
+ baseType.kind === "named" &&
119
+ baseType.methods?.has(expr.field)
120
+ ) {
121
+ methodType = baseType.methods.get(expr.field);
122
+ }
123
+ if (methodType) {
116
124
  // Return a func type with the receiver prepended to params
117
125
  expr._isMethodExpr = true;
118
126
  expr._methodExprRecv = baseType;
@@ -129,7 +137,10 @@ export const expressionCheckMethods = {
129
137
  if (ft?.kind === "func") {
130
138
  let base = baseType.kind === "named" ? baseType.underlying : baseType;
131
139
  base = this.resolveType(base);
132
- if (base?.kind === "struct" && base.methods?.has(expr.field)) {
140
+ if (
141
+ (base?.kind === "struct" && base.methods?.has(expr.field)) ||
142
+ (baseType.kind === "named" && baseType.methods?.has(expr.field))
143
+ ) {
133
144
  expr._isMethodValue = true;
134
145
  }
135
146
  }
@@ -140,9 +151,14 @@ export const expressionCheckMethods = {
140
151
  const bt = this.checkExpr(expr.expr, scope);
141
152
  this.checkExpr(expr.index, scope);
142
153
  if (isAny(bt)) return ANY;
143
- if (bt.kind === "slice" || bt.kind === "array") {
154
+ // Named types (e.g. type Nums []int) are indexable via their underlying
155
+ const btu =
156
+ bt.kind === "named"
157
+ ? (this.resolveType(bt.underlying) ?? bt.underlying)
158
+ : bt;
159
+ if (btu.kind === "slice" || btu.kind === "array") {
144
160
  // Compile-time bounds checking for arrays
145
- if (bt.kind === "array" && bt.size != null) {
161
+ if (btu.kind === "array" && btu.size != null) {
146
162
  const idx = this._constIntValue(expr.index);
147
163
  if (idx !== null) {
148
164
  if (idx < 0) {
@@ -150,7 +166,7 @@ export const expressionCheckMethods = {
150
166
  `invalid array index ${idx} (index must not be negative)`,
151
167
  expr,
152
168
  );
153
- } else if (idx >= bt.size) {
169
+ } else if (idx >= btu.size) {
154
170
  this.err(
155
171
  `invalid array index ${idx} (out of bounds for ${typeStr(bt)})`,
156
172
  expr,
@@ -158,11 +174,11 @@ export const expressionCheckMethods = {
158
174
  }
159
175
  }
160
176
  }
161
- return bt.elem;
177
+ return btu.elem;
162
178
  }
163
- if (bt.kind === "map") {
164
- expr._mapValueType = bt.value; // for codegen zero-value fallback
165
- return bt.value;
179
+ if (btu.kind === "map") {
180
+ expr._mapValueType = btu.value; // for codegen zero-value fallback
181
+ return btu.value;
166
182
  }
167
183
  if (isString(bt)) return INT; // byte
168
184
  return this.err(`Cannot index type ${typeStr(bt)}`, expr);
@@ -410,6 +426,19 @@ export const expressionCheckMethods = {
410
426
 
411
427
  if (isAny(fnType)) return ANY;
412
428
 
429
+ // Named type used as a constructor/conversion: Greeter(fn), NodeFunc(fn)
430
+ // The callee is a type name, not a callable variable.
431
+ if (fnType.kind === "named" && expr.func._isTypeRef) {
432
+ expr._isTypeConversion = true;
433
+ expr._conversionTargetType = fnType;
434
+ return fnType;
435
+ }
436
+
437
+ // Named func types (e.g. type Handler func(int) int) are callable via variable
438
+ if (fnType.kind === "named" && fnType.underlying?.kind === "func") {
439
+ fnType = fnType.underlying;
440
+ }
441
+
413
442
  // Generic function inference
414
443
  if (fnType.kind === "generic") {
415
444
  const typeArgs = this.inferTypeArgs(fnType, argTypes);