capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

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