generics.c++ (23106B)
1 // Copyright (c) 2013-2020 Sandstorm Development Group, Inc. and contributors 2 // Licensed under the MIT License: 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE. 21 22 #include "generics.h" 23 #include "parser.h" // for expressionString() 24 25 namespace capnp { 26 namespace compiler { 27 28 BrandedDecl::BrandedDecl(BrandedDecl& other) 29 : body(other.body), 30 source(other.source) { 31 if (body.is<Resolver::ResolvedDecl>()) { 32 brand = kj::addRef(*other.brand); 33 } 34 } 35 36 BrandedDecl& BrandedDecl::operator=(BrandedDecl& other) { 37 body = other.body; 38 source = other.source; 39 if (body.is<Resolver::ResolvedDecl>()) { 40 brand = kj::addRef(*other.brand); 41 } 42 return *this; 43 } 44 45 kj::Maybe<BrandedDecl> BrandedDecl::applyParams( 46 kj::Array<BrandedDecl> params, Expression::Reader subSource) { 47 if (body.is<Resolver::ResolvedParameter>()) { 48 return nullptr; 49 } else { 50 return brand->setParams(kj::mv(params), body.get<Resolver::ResolvedDecl>().kind, subSource) 51 .map([&](kj::Own<BrandScope>&& scope) { 52 BrandedDecl result = *this; 53 result.brand = kj::mv(scope); 54 result.source = subSource; 55 return result; 56 }); 57 } 58 } 59 60 kj::Maybe<BrandedDecl> BrandedDecl::getMember( 61 kj::StringPtr memberName, Expression::Reader subSource) { 62 if (body.is<Resolver::ResolvedParameter>()) { 63 return nullptr; 64 } else KJ_IF_MAYBE(r, body.get<Resolver::ResolvedDecl>().resolver->resolveMember(memberName)) { 65 return brand->interpretResolve(*body.get<Resolver::ResolvedDecl>().resolver, *r, subSource); 66 } else { 67 return nullptr; 68 } 69 } 70 71 kj::Maybe<Declaration::Which> BrandedDecl::getKind() { 72 if (body.is<Resolver::ResolvedParameter>()) { 73 return nullptr; 74 } else { 75 return body.get<Resolver::ResolvedDecl>().kind; 76 } 77 } 78 79 kj::Maybe<BrandedDecl&> BrandedDecl::getListParam() { 80 KJ_REQUIRE(body.is<Resolver::ResolvedDecl>()); 81 82 auto& decl = body.get<Resolver::ResolvedDecl>(); 83 KJ_REQUIRE(decl.kind == Declaration::BUILTIN_LIST); 84 85 auto params = KJ_ASSERT_NONNULL(brand->getParams(decl.id)); 86 if (params.size() != 1) { 87 return nullptr; 88 } else { 89 return params[0]; 90 } 91 } 92 93 Resolver::ResolvedParameter BrandedDecl::asVariable() { 94 KJ_REQUIRE(body.is<Resolver::ResolvedParameter>()); 95 96 return body.get<Resolver::ResolvedParameter>(); 97 } 98 99 bool BrandedDecl::compileAsType( 100 ErrorReporter& errorReporter, schema::Type::Builder target) { 101 KJ_IF_MAYBE(kind, getKind()) { 102 switch (*kind) { 103 case Declaration::ENUM: { 104 auto enum_ = target.initEnum(); 105 enum_.setTypeId(getIdAndFillBrand([&]() { return enum_.initBrand(); })); 106 return true; 107 } 108 109 case Declaration::STRUCT: { 110 auto struct_ = target.initStruct(); 111 struct_.setTypeId(getIdAndFillBrand([&]() { return struct_.initBrand(); })); 112 return true; 113 } 114 115 case Declaration::INTERFACE: { 116 auto interface = target.initInterface(); 117 interface.setTypeId(getIdAndFillBrand([&]() { return interface.initBrand(); })); 118 return true; 119 } 120 121 case Declaration::BUILTIN_LIST: { 122 auto elementType = target.initList().initElementType(); 123 124 KJ_IF_MAYBE(param, getListParam()) { 125 if (!param->compileAsType(errorReporter, elementType)) { 126 return false; 127 } 128 } else { 129 addError(errorReporter, "'List' requires exactly one parameter."); 130 return false; 131 } 132 133 if (elementType.isAnyPointer()) { 134 auto unconstrained = elementType.getAnyPointer().getUnconstrained(); 135 136 if (unconstrained.isAnyKind()) { 137 addError(errorReporter, "'List(AnyPointer)' is not supported."); 138 // Seeing List(AnyPointer) later can mess things up, so change the type to Void. 139 elementType.setVoid(); 140 return false; 141 } else if (unconstrained.isStruct()) { 142 addError(errorReporter, "'List(AnyStruct)' is not supported."); 143 // Seeing List(AnyStruct) later can mess things up, so change the type to Void. 144 elementType.setVoid(); 145 return false; 146 } 147 } 148 149 return true; 150 } 151 152 case Declaration::BUILTIN_VOID: target.setVoid(); return true; 153 case Declaration::BUILTIN_BOOL: target.setBool(); return true; 154 case Declaration::BUILTIN_INT8: target.setInt8(); return true; 155 case Declaration::BUILTIN_INT16: target.setInt16(); return true; 156 case Declaration::BUILTIN_INT32: target.setInt32(); return true; 157 case Declaration::BUILTIN_INT64: target.setInt64(); return true; 158 case Declaration::BUILTIN_U_INT8: target.setUint8(); return true; 159 case Declaration::BUILTIN_U_INT16: target.setUint16(); return true; 160 case Declaration::BUILTIN_U_INT32: target.setUint32(); return true; 161 case Declaration::BUILTIN_U_INT64: target.setUint64(); return true; 162 case Declaration::BUILTIN_FLOAT32: target.setFloat32(); return true; 163 case Declaration::BUILTIN_FLOAT64: target.setFloat64(); return true; 164 case Declaration::BUILTIN_TEXT: target.setText(); return true; 165 case Declaration::BUILTIN_DATA: target.setData(); return true; 166 167 case Declaration::BUILTIN_OBJECT: 168 addError(errorReporter, 169 "As of Cap'n Proto 0.4, 'Object' has been renamed to 'AnyPointer'. Sorry for the " 170 "inconvenience, and thanks for being an early adopter. :)"); 171 KJ_FALLTHROUGH; 172 case Declaration::BUILTIN_ANY_POINTER: 173 target.initAnyPointer().initUnconstrained().setAnyKind(); 174 return true; 175 case Declaration::BUILTIN_ANY_STRUCT: 176 target.initAnyPointer().initUnconstrained().setStruct(); 177 return true; 178 case Declaration::BUILTIN_ANY_LIST: 179 target.initAnyPointer().initUnconstrained().setList(); 180 return true; 181 case Declaration::BUILTIN_CAPABILITY: 182 target.initAnyPointer().initUnconstrained().setCapability(); 183 return true; 184 185 case Declaration::FILE: 186 case Declaration::USING: 187 case Declaration::CONST: 188 case Declaration::ENUMERANT: 189 case Declaration::FIELD: 190 case Declaration::UNION: 191 case Declaration::GROUP: 192 case Declaration::METHOD: 193 case Declaration::ANNOTATION: 194 case Declaration::NAKED_ID: 195 case Declaration::NAKED_ANNOTATION: 196 addError(errorReporter, kj::str("'", toString(), "' is not a type.")); 197 return false; 198 } 199 200 KJ_UNREACHABLE; 201 } else { 202 // Oh, this is a type variable. 203 auto var = asVariable(); 204 if (var.id == 0) { 205 // This is actually a method implicit parameter. 206 auto builder = target.initAnyPointer().initImplicitMethodParameter(); 207 builder.setParameterIndex(var.index); 208 return true; 209 } else { 210 auto builder = target.initAnyPointer().initParameter(); 211 builder.setScopeId(var.id); 212 builder.setParameterIndex(var.index); 213 return true; 214 } 215 } 216 } 217 218 Resolver::ResolveResult BrandedDecl::asResolveResult( 219 uint64_t scopeId, schema::Brand::Builder brandBuilder) { 220 auto result = body; 221 if (result.is<Resolver::ResolvedDecl>()) { 222 // May need to compile our context as the "brand". 223 224 result.get<Resolver::ResolvedDecl>().scopeId = scopeId; 225 226 getIdAndFillBrand([&]() { 227 result.get<Resolver::ResolvedDecl>().brand = brandBuilder.asReader(); 228 return brandBuilder; 229 }); 230 } 231 return result; 232 } 233 234 kj::String BrandedDecl::toString() { 235 return expressionString(source); 236 } 237 238 kj::String BrandedDecl::toDebugString() { 239 if (body.is<Resolver::ResolvedParameter>()) { 240 auto variable = body.get<Resolver::ResolvedParameter>(); 241 return kj::str("variable(", variable.id, ", ", variable.index, ")"); 242 } else { 243 auto decl = body.get<Resolver::ResolvedDecl>(); 244 return kj::str("decl(", decl.id, ", ", (uint)decl.kind, "')"); 245 } 246 } 247 248 BrandScope::BrandScope(ErrorReporter& errorReporter, uint64_t startingScopeId, 249 uint startingScopeParamCount, Resolver& startingScope) 250 : errorReporter(errorReporter), parent(nullptr), leafId(startingScopeId), 251 leafParamCount(startingScopeParamCount), inherited(true) { 252 // Create all lexical parent scopes, all with no brand bindings. 253 KJ_IF_MAYBE(p, startingScope.getParent()) { 254 parent = kj::refcounted<BrandScope>( 255 errorReporter, p->id, p->genericParamCount, *p->resolver); 256 } 257 } 258 259 bool BrandScope::isGeneric() { 260 if (leafParamCount > 0) return true; 261 262 KJ_IF_MAYBE(p, parent) { 263 return p->get()->isGeneric(); 264 } else { 265 return false; 266 } 267 } 268 269 kj::Own<BrandScope> BrandScope::push(uint64_t typeId, uint paramCount) { 270 return kj::refcounted<BrandScope>(kj::addRef(*this), typeId, paramCount); 271 } 272 273 kj::Maybe<kj::Own<BrandScope>> BrandScope::setParams( 274 kj::Array<BrandedDecl> params, Declaration::Which genericType, Expression::Reader source) { 275 if (this->params.size() != 0) { 276 errorReporter.addErrorOn(source, "Double-application of generic parameters."); 277 return nullptr; 278 } else if (params.size() > leafParamCount) { 279 if (leafParamCount == 0) { 280 errorReporter.addErrorOn(source, "Declaration does not accept generic parameters."); 281 } else { 282 errorReporter.addErrorOn(source, "Too many generic parameters."); 283 } 284 return nullptr; 285 } else if (params.size() < leafParamCount) { 286 errorReporter.addErrorOn(source, "Not enough generic parameters."); 287 return nullptr; 288 } else { 289 if (genericType != Declaration::BUILTIN_LIST) { 290 for (auto& param: params) { 291 KJ_IF_MAYBE(kind, param.getKind()) { 292 switch (*kind) { 293 case Declaration::BUILTIN_LIST: 294 case Declaration::BUILTIN_TEXT: 295 case Declaration::BUILTIN_DATA: 296 case Declaration::BUILTIN_ANY_POINTER: 297 case Declaration::STRUCT: 298 case Declaration::INTERFACE: 299 break; 300 301 default: 302 param.addError(errorReporter, 303 "Sorry, only pointer types can be used as generic parameters."); 304 break; 305 } 306 } 307 } 308 } 309 310 return kj::refcounted<BrandScope>(*this, kj::mv(params)); 311 } 312 } 313 314 kj::Own<BrandScope> BrandScope::pop(uint64_t newLeafId) { 315 if (leafId == newLeafId) { 316 return kj::addRef(*this); 317 } 318 KJ_IF_MAYBE(p, parent) { 319 return (*p)->pop(newLeafId); 320 } else { 321 // Looks like we're moving into a whole top-level scope. 322 return kj::refcounted<BrandScope>(errorReporter, newLeafId); 323 } 324 } 325 326 kj::Maybe<BrandedDecl> BrandScope::lookupParameter( 327 Resolver& resolver, uint64_t scopeId, uint index) { 328 // Returns null if the param should be inherited from the client scope. 329 330 if (scopeId == leafId) { 331 if (index < params.size()) { 332 return params[index]; 333 } else if (inherited) { 334 return nullptr; 335 } else { 336 // Unbound and not inherited, so return AnyPointer. 337 auto decl = resolver.resolveBuiltin(Declaration::BUILTIN_ANY_POINTER); 338 return BrandedDecl(decl, 339 evaluateBrand(resolver, decl, List<schema::Brand::Scope>::Reader()), 340 Expression::Reader()); 341 } 342 } else KJ_IF_MAYBE(p, parent) { 343 return p->get()->lookupParameter(resolver, scopeId, index); 344 } else { 345 KJ_FAIL_REQUIRE("scope is not a parent"); 346 } 347 } 348 349 kj::Maybe<kj::ArrayPtr<BrandedDecl>> BrandScope::getParams(uint64_t scopeId) { 350 // Returns null if params at the requested scope should be inherited from the client scope. 351 352 if (scopeId == leafId) { 353 if (inherited) { 354 return nullptr; 355 } else { 356 return params.asPtr(); 357 } 358 } else KJ_IF_MAYBE(p, parent) { 359 return p->get()->getParams(scopeId); 360 } else { 361 KJ_FAIL_REQUIRE("scope is not a parent"); 362 } 363 } 364 365 BrandedDecl BrandScope::interpretResolve( 366 Resolver& resolver, Resolver::ResolveResult& result, Expression::Reader source) { 367 if (result.is<Resolver::ResolvedDecl>()) { 368 auto& decl = result.get<Resolver::ResolvedDecl>(); 369 370 auto scope = pop(decl.scopeId); 371 KJ_IF_MAYBE(brand, decl.brand) { 372 scope = scope->evaluateBrand(resolver, decl, brand->getScopes()); 373 } else { 374 scope = scope->push(decl.id, decl.genericParamCount); 375 } 376 377 return BrandedDecl(decl, kj::mv(scope), source); 378 } else { 379 auto& param = result.get<Resolver::ResolvedParameter>(); 380 KJ_IF_MAYBE(p, lookupParameter(resolver, param.id, param.index)) { 381 return *p; 382 } else { 383 return BrandedDecl(param, source); 384 } 385 } 386 } 387 388 kj::Own<BrandScope> BrandScope::evaluateBrand( 389 Resolver& resolver, Resolver::ResolvedDecl decl, 390 List<schema::Brand::Scope>::Reader brand, uint index) { 391 auto result = kj::refcounted<BrandScope>(errorReporter, decl.id); 392 result->leafParamCount = decl.genericParamCount; 393 394 // Fill in `params`. 395 if (index < brand.size()) { 396 auto nextScope = brand[index]; 397 if (decl.id == nextScope.getScopeId()) { 398 // Initialize our parameters. 399 400 switch (nextScope.which()) { 401 case schema::Brand::Scope::BIND: { 402 auto bindings = nextScope.getBind(); 403 auto params = kj::heapArrayBuilder<BrandedDecl>(bindings.size()); 404 for (auto binding: bindings) { 405 switch (binding.which()) { 406 case schema::Brand::Binding::UNBOUND: { 407 // Build an AnyPointer-equivalent. 408 auto anyPointerDecl = resolver.resolveBuiltin(Declaration::BUILTIN_ANY_POINTER); 409 params.add(BrandedDecl(anyPointerDecl, 410 kj::refcounted<BrandScope>(errorReporter, anyPointerDecl.scopeId), 411 Expression::Reader())); 412 break; 413 } 414 415 case schema::Brand::Binding::TYPE: 416 // Reverse this schema::Type back into a BrandedDecl. 417 params.add(decompileType(resolver, binding.getType())); 418 break; 419 } 420 } 421 result->params = params.finish(); 422 break; 423 } 424 425 case schema::Brand::Scope::INHERIT: 426 KJ_IF_MAYBE(p, getParams(decl.id)) { 427 result->params = kj::heapArray(*p); 428 } else { 429 result->inherited = true; 430 } 431 break; 432 } 433 434 // Parent should start one level deeper in the list. 435 ++index; 436 } 437 } 438 439 // Fill in `parent`. 440 KJ_IF_MAYBE(parent, decl.resolver->getParent()) { 441 result->parent = evaluateBrand(resolver, *parent, brand, index); 442 } 443 444 return result; 445 } 446 447 BrandedDecl BrandScope::decompileType( 448 Resolver& resolver, schema::Type::Reader type) { 449 auto builtin = [&](Declaration::Which which) -> BrandedDecl { 450 auto decl = resolver.resolveBuiltin(which); 451 return BrandedDecl(decl, 452 evaluateBrand(resolver, decl, List<schema::Brand::Scope>::Reader()), 453 Expression::Reader()); 454 }; 455 456 switch (type.which()) { 457 case schema::Type::VOID: return builtin(Declaration::BUILTIN_VOID); 458 case schema::Type::BOOL: return builtin(Declaration::BUILTIN_BOOL); 459 case schema::Type::INT8: return builtin(Declaration::BUILTIN_INT8); 460 case schema::Type::INT16: return builtin(Declaration::BUILTIN_INT16); 461 case schema::Type::INT32: return builtin(Declaration::BUILTIN_INT32); 462 case schema::Type::INT64: return builtin(Declaration::BUILTIN_INT64); 463 case schema::Type::UINT8: return builtin(Declaration::BUILTIN_U_INT8); 464 case schema::Type::UINT16: return builtin(Declaration::BUILTIN_U_INT16); 465 case schema::Type::UINT32: return builtin(Declaration::BUILTIN_U_INT32); 466 case schema::Type::UINT64: return builtin(Declaration::BUILTIN_U_INT64); 467 case schema::Type::FLOAT32: return builtin(Declaration::BUILTIN_FLOAT32); 468 case schema::Type::FLOAT64: return builtin(Declaration::BUILTIN_FLOAT64); 469 case schema::Type::TEXT: return builtin(Declaration::BUILTIN_TEXT); 470 case schema::Type::DATA: return builtin(Declaration::BUILTIN_DATA); 471 472 case schema::Type::ENUM: { 473 auto enumType = type.getEnum(); 474 Resolver::ResolvedDecl decl = resolver.resolveId(enumType.getTypeId()); 475 return BrandedDecl(decl, 476 evaluateBrand(resolver, decl, enumType.getBrand().getScopes()), 477 Expression::Reader()); 478 } 479 480 case schema::Type::INTERFACE: { 481 auto interfaceType = type.getInterface(); 482 Resolver::ResolvedDecl decl = resolver.resolveId(interfaceType.getTypeId()); 483 return BrandedDecl(decl, 484 evaluateBrand(resolver, decl, interfaceType.getBrand().getScopes()), 485 Expression::Reader()); 486 } 487 488 case schema::Type::STRUCT: { 489 auto structType = type.getStruct(); 490 Resolver::ResolvedDecl decl = resolver.resolveId(structType.getTypeId()); 491 return BrandedDecl(decl, 492 evaluateBrand(resolver, decl, structType.getBrand().getScopes()), 493 Expression::Reader()); 494 } 495 496 case schema::Type::LIST: { 497 auto elementType = decompileType(resolver, type.getList().getElementType()); 498 return KJ_ASSERT_NONNULL(builtin(Declaration::BUILTIN_LIST) 499 .applyParams(kj::heapArray(&elementType, 1), Expression::Reader())); 500 } 501 502 case schema::Type::ANY_POINTER: { 503 auto anyPointer = type.getAnyPointer(); 504 switch (anyPointer.which()) { 505 case schema::Type::AnyPointer::UNCONSTRAINED: 506 return builtin(Declaration::BUILTIN_ANY_POINTER); 507 508 case schema::Type::AnyPointer::PARAMETER: { 509 auto param = anyPointer.getParameter(); 510 auto id = param.getScopeId(); 511 uint index = param.getParameterIndex(); 512 KJ_IF_MAYBE(binding, lookupParameter(resolver, id, index)) { 513 return *binding; 514 } else { 515 return BrandedDecl(Resolver::ResolvedParameter {id, index}, Expression::Reader()); 516 } 517 } 518 519 case schema::Type::AnyPointer::IMPLICIT_METHOD_PARAMETER: 520 KJ_FAIL_ASSERT("Alias pointed to implicit method type parameter?"); 521 } 522 523 KJ_UNREACHABLE; 524 } 525 } 526 527 KJ_UNREACHABLE; 528 } 529 530 kj::Maybe<BrandedDecl> BrandScope::compileDeclExpression( 531 Expression::Reader source, Resolver& resolver, 532 ImplicitParams implicitMethodParams) { 533 switch (source.which()) { 534 case Expression::UNKNOWN: 535 // Error reported earlier. 536 return nullptr; 537 538 case Expression::POSITIVE_INT: 539 case Expression::NEGATIVE_INT: 540 case Expression::FLOAT: 541 case Expression::STRING: 542 case Expression::BINARY: 543 case Expression::LIST: 544 case Expression::TUPLE: 545 case Expression::EMBED: 546 errorReporter.addErrorOn(source, "Expected name."); 547 return nullptr; 548 549 case Expression::RELATIVE_NAME: { 550 auto name = source.getRelativeName(); 551 auto nameValue = name.getValue(); 552 553 // Check implicit method params first. 554 for (auto i: kj::indices(implicitMethodParams.params)) { 555 if (implicitMethodParams.params[i].getName() == nameValue) { 556 if (implicitMethodParams.scopeId == 0) { 557 return BrandedDecl::implicitMethodParam(i); 558 } else { 559 return BrandedDecl(Resolver::ResolvedParameter { 560 implicitMethodParams.scopeId, static_cast<uint16_t>(i) }, 561 Expression::Reader()); 562 } 563 } 564 } 565 566 KJ_IF_MAYBE(r, resolver.resolve(nameValue)) { 567 return interpretResolve(resolver, *r, source); 568 } else { 569 errorReporter.addErrorOn(name, kj::str("Not defined: ", nameValue)); 570 return nullptr; 571 } 572 } 573 574 case Expression::ABSOLUTE_NAME: { 575 auto name = source.getAbsoluteName(); 576 KJ_IF_MAYBE(r, resolver.getTopScope().resolver->resolveMember(name.getValue())) { 577 return interpretResolve(resolver, *r, source); 578 } else { 579 errorReporter.addErrorOn(name, kj::str("Not defined: ", name.getValue())); 580 return nullptr; 581 } 582 } 583 584 case Expression::IMPORT: { 585 auto filename = source.getImport(); 586 KJ_IF_MAYBE(decl, resolver.resolveImport(filename.getValue())) { 587 // Import is always a root scope, so create a fresh BrandScope. 588 return BrandedDecl(*decl, kj::refcounted<BrandScope>( 589 errorReporter, decl->id, decl->genericParamCount, *decl->resolver), source); 590 } else { 591 errorReporter.addErrorOn(filename, kj::str("Import failed: ", filename.getValue())); 592 return nullptr; 593 } 594 } 595 596 case Expression::APPLICATION: { 597 auto app = source.getApplication(); 598 KJ_IF_MAYBE(decl, compileDeclExpression(app.getFunction(), resolver, implicitMethodParams)) { 599 // Compile all params. 600 auto params = app.getParams(); 601 auto compiledParams = kj::heapArrayBuilder<BrandedDecl>(params.size()); 602 bool paramFailed = false; 603 for (auto param: params) { 604 if (param.isNamed()) { 605 errorReporter.addErrorOn(param.getNamed(), "Named parameter not allowed here."); 606 } 607 608 KJ_IF_MAYBE(d, compileDeclExpression(param.getValue(), resolver, implicitMethodParams)) { 609 compiledParams.add(kj::mv(*d)); 610 } else { 611 // Param failed to compile. Error was already reported. 612 paramFailed = true; 613 } 614 }; 615 616 if (paramFailed) { 617 return kj::mv(*decl); 618 } 619 620 // Add the parameters to the brand. 621 KJ_IF_MAYBE(applied, decl->applyParams(compiledParams.finish(), source)) { 622 return kj::mv(*applied); 623 } else { 624 // Error already reported. Ignore parameters. 625 return kj::mv(*decl); 626 } 627 } else { 628 // error already reported 629 return nullptr; 630 } 631 } 632 633 case Expression::MEMBER: { 634 auto member = source.getMember(); 635 KJ_IF_MAYBE(decl, compileDeclExpression(member.getParent(), resolver, implicitMethodParams)) { 636 auto name = member.getName(); 637 KJ_IF_MAYBE(memberDecl, decl->getMember(name.getValue(), source)) { 638 return kj::mv(*memberDecl); 639 } else { 640 errorReporter.addErrorOn(name, kj::str( 641 "'", expressionString(member.getParent()), 642 "' has no member named '", name.getValue(), "'")); 643 return nullptr; 644 } 645 } else { 646 // error already reported 647 return nullptr; 648 } 649 } 650 } 651 652 KJ_UNREACHABLE; 653 } 654 655 } // namespace compiler 656 } // namespace capnp