コード例 #1
2
static void initDocGenericParams(const Decl *D, DocEntityInfo &Info) {
  GenericParamList *GenParams = nullptr;
  if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
    GenParams = NTD->getGenericParams();
  } else if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
    GenParams = AFD->getGenericParams();
  } else if (auto *ExtD = dyn_cast<ExtensionDecl>(D)) {
    GenParams = ExtD->getGenericParams();
  }

  if (!GenParams)
    return;

  for (auto *GP : GenParams->getParams()) {
    if (GP->isImplicit())
      continue;
    DocGenericParam Param;
    Param.Name = GP->getNameStr();
    if (!GP->getInherited().empty()) {
      llvm::raw_string_ostream OS(Param.Inherits);
      GP->getInherited()[0].getType().print(OS);
    }

    Info.GenericParams.push_back(Param);
  }
  for (auto &Req : GenParams->getRequirements()) {
    std::string ReqStr;
    llvm::raw_string_ostream OS(ReqStr);
    Req.printAsWritten(OS);
    OS.flush();
    Info.GenericRequirements.push_back(std::move(ReqStr));
  }
}
コード例 #2
0
ファイル: TypeCheckGeneric.cpp プロジェクト: Ael-susen/swift
void TypeChecker::markInvalidGenericSignature(ValueDecl *VD) {
  GenericParamList *genericParams;
  if (auto *AFD = dyn_cast<AbstractFunctionDecl>(VD))
    genericParams = AFD->getGenericParams();
  else
    genericParams = cast<GenericTypeDecl>(VD)->getGenericParams();

  // If there aren't any generic parameters at this level, we're done.
  if (genericParams == nullptr)
    return;

  DeclContext *DC = VD->getDeclContext();
  ArchetypeBuilder builder = createArchetypeBuilder(DC->getParentModule());

  if (auto sig = DC->getGenericSignatureOfContext())
    builder.addGenericSignature(sig, true);

  // Visit each of the generic parameters.
  for (auto param : *genericParams)
    builder.addGenericParameter(param);

  // Wire up the archetypes.
  for (auto GP : *genericParams)
    GP->setArchetype(builder.getArchetype(GP));

  genericParams->setAllArchetypes(
      Context.AllocateCopy(builder.getAllArchetypes()));
}
コード例 #3
0
ファイル: DeclContext.cpp プロジェクト: benrimmington/swift
GenericTypeParamType *DeclContext::getProtocolSelfType() const {
  assert(getSelfProtocolDecl() && "not a protocol");

  GenericParamList *genericParams;
  if (auto proto = dyn_cast<ProtocolDecl>(this)) {
    genericParams = proto->getGenericParams();
  } else {
    genericParams = cast<ExtensionDecl>(this)->getGenericParams();
  }

  if (genericParams == nullptr)
    return nullptr;

  return genericParams->getParams().front()
      ->getDeclaredInterfaceType()
      ->castTo<GenericTypeParamType>();
}
コード例 #4
0
ファイル: ParseGeneric.cpp プロジェクト: 464033679/swift
ParserResult<GenericParamList> Parser::maybeParseGenericParams() {
  if (!startsWithLess(Tok))
    return nullptr;

  if (!isInSILMode())
    return parseGenericParameters();

  // In SIL mode, we can have multiple generic parameter lists, with the
  // first one being the outmost generic parameter list.
  GenericParamList *gpl = nullptr, *outer_gpl = nullptr;
  do {
    gpl = parseGenericParameters().getPtrOrNull();
    if (!gpl)
      return nullptr;

    if (outer_gpl)
      gpl->setOuterParameters(outer_gpl);
    outer_gpl = gpl;
  } while (startsWithLess(Tok));
  return makeParserResult(gpl);
}
コード例 #5
0
ファイル: SILGenConvert.cpp プロジェクト: goodcyg/swift
static Substitution getSimpleSubstitution(GenericParamList &generics,
                                          CanType typeArg) {
  assert(generics.getParams().size() == 1);
  auto typeParamDecl = generics.getParams().front();
  return Substitution{typeParamDecl->getArchetype(), typeArg, {}};
}
コード例 #6
0
ファイル: ParseType.cpp プロジェクト: nauzetvm/Apple-Swift
/// parseType
///   type:
///     attribute-list type-function
///     attribute-list type-array
///
///   type-function:
///     type-simple '->' type
///
ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
                                         bool HandleCodeCompletion) {
  // Parse attributes.
  TypeAttributes attrs;
  parseTypeAttributeList(attrs);

  // Parse Generic Parameters. Generic Parameters are visible in the function
  // body.
  GenericParamList *generics = nullptr;
  if (isInSILMode()) {
    generics = maybeParseGenericParams().getPtrOrNull();
  }

  ParserResult<TypeRepr> ty = parseTypeSimple(MessageID, HandleCodeCompletion);
  if (ty.hasCodeCompletion())
    return makeParserCodeCompletionResult<TypeRepr>();

  if (ty.isNull())
    return nullptr;

  // Parse a throws specifier.  'throw' is probably a typo for 'throws',
  // but in local contexts we could just be at the end of a statement,
  // so we need to check for the arrow.
  ParserPosition beforeThrowsPos;
  SourceLoc throwsLoc;
  bool rethrows = false;
  if (Tok.isAny(tok::kw_throws, tok::kw_rethrows) ||
      (Tok.is(tok::kw_throw) && peekToken().is(tok::arrow))) {
    if (Tok.is(tok::kw_throw)) {
      diagnose(Tok.getLoc(), diag::throw_in_function_type)
        .fixItReplace(Tok.getLoc(), "throws");
    }

    beforeThrowsPos = getParserPosition();
    rethrows = Tok.is(tok::kw_rethrows);
    throwsLoc = consumeToken();
  }

  // Handle type-function if we have an arrow.
  SourceLoc arrowLoc;
  if (consumeIf(tok::arrow, arrowLoc)) {
    ParserResult<TypeRepr> SecondHalf =
      parseType(diag::expected_type_function_result);
    if (SecondHalf.hasCodeCompletion())
      return makeParserCodeCompletionResult<TypeRepr>();
    if (SecondHalf.isNull())
      return nullptr;
    if (rethrows) {
      // 'rethrows' is only allowed on function declarations for now.
      diagnose(throwsLoc, diag::rethrowing_function_type);
    }
    auto fnTy = new (Context) FunctionTypeRepr(generics, ty.get(),
                                               throwsLoc,
                                               arrowLoc,
                                               SecondHalf.get());
    return makeParserResult(applyAttributeToType(fnTy, attrs));
  } else if (throwsLoc.isValid()) {
    // Don't consume 'throws', so we can emit a more useful diagnostic when
    // parsing a function decl.
    restoreParserPosition(beforeThrowsPos);
    return ty;
  }
  
  // Only function types may be generic.
  if (generics) {
    auto brackets = generics->getSourceRange();
    diagnose(brackets.Start, diag::generic_non_function);
  }

  // Parse legacy array types for migration.
  while (ty.isNonNull() && !Tok.isAtStartOfLine()) {
    if (Tok.is(tok::l_square)) {
      ty = parseTypeArray(ty.get());
    } else {
      break;
    }
  }

  if (ty.isNonNull() && !ty.hasCodeCompletion()) {
    ty = makeParserResult(applyAttributeToType(ty.get(), attrs));
  }
  return ty;
}
コード例 #7
0
ファイル: LookupVisibleDecls.cpp プロジェクト: erica/swift
static void lookupVisibleDeclsImpl(VisibleDeclConsumer &Consumer,
                                   const DeclContext *DC,
                                   LazyResolver *TypeResolver,
                                   bool IncludeTopLevel, SourceLoc Loc) {
  const ModuleDecl &M = *DC->getParentModule();
  const SourceManager &SM = DC->getASTContext().SourceMgr;
  auto Reason = DeclVisibilityKind::MemberOfCurrentNominal;

  // If we are inside of a method, check to see if there are any ivars in scope,
  // and if so, whether this is a reference to one of them.
  while (!DC->isModuleScopeContext()) {
    GenericParamList *GenericParams = nullptr;
    Type ExtendedType;
    auto LS = LookupState::makeUnqualified();

    // Skip initializer contexts, we will not find any declarations there.
    if (isa<Initializer>(DC)) {
      DC = DC->getParent();
      LS = LS.withOnMetatype();
    }

    // We don't look for generic parameters if we are in the context of a
    // nominal type: they will be looked up anyways via `lookupVisibleMemberDecls`.
    if (DC && !isa<NominalTypeDecl>(DC)) {
      if (auto *decl = DC->getAsDecl()) {
        if (auto GC = decl->getAsGenericContext()) {
          auto params = GC->getGenericParams();
          namelookup::FindLocalVal(SM, Loc, Consumer).checkGenericParams(params);
        }
      }
    }

    if (auto *SE = dyn_cast<SubscriptDecl>(DC)) {
      ExtendedType = SE->getDeclContext()->getSelfTypeInContext();
      DC = DC->getParent();
    } else if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC)) {

      // Look for local variables; normally, the parser resolves these
      // for us, but it can't do the right thing inside local types.
      // FIXME: when we can parse and typecheck the function body partially for
      // code completion, AFD->getBody() check can be removed.
      if (Loc.isValid() && AFD->getBody()) {
        namelookup::FindLocalVal(SM, Loc, Consumer).visit(AFD->getBody());
      }

      if (auto *P = AFD->getImplicitSelfDecl()) {
        namelookup::FindLocalVal(SM, Loc, Consumer).checkValueDecl(
          const_cast<ParamDecl *>(P), DeclVisibilityKind::FunctionParameter);
      }

      namelookup::FindLocalVal(SM, Loc, Consumer).checkParameterList(
        AFD->getParameters());

      GenericParams = AFD->getGenericParams();

      if (AFD->getDeclContext()->isTypeContext()) {
        ExtendedType = AFD->getDeclContext()->getSelfTypeInContext();
        DC = DC->getParent();

        if (auto *FD = dyn_cast<FuncDecl>(AFD))
          if (FD->isStatic())
            ExtendedType = MetatypeType::get(ExtendedType);
      }
    } else if (auto CE = dyn_cast<ClosureExpr>(DC)) {
      if (Loc.isValid()) {
        namelookup::FindLocalVal(SM, Loc, Consumer).visit(CE->getBody());
        if (auto P = CE->getParameters()) {
          namelookup::FindLocalVal(SM, Loc, Consumer).checkParameterList(P);
        }
      }
    } else if (auto ED = dyn_cast<ExtensionDecl>(DC)) {
      ExtendedType = ED->getSelfTypeInContext();
    } else if (auto ND = dyn_cast<NominalTypeDecl>(DC)) {
      ExtendedType = ND->getSelfTypeInContext();
    }

    // If we're inside a function context, we've already moved to
    // the parent DC, so we have to check the function's generic
    // parameters first.
    if (GenericParams) {
      namelookup::FindLocalVal localVal(SM, Loc, Consumer);
      localVal.checkGenericParams(GenericParams);
    }

    // Check the generic parameters of our context.
    GenericParamList *dcGenericParams = nullptr;
    if (auto nominal = dyn_cast<NominalTypeDecl>(DC))
      dcGenericParams = nominal->getGenericParams();
    else if (auto ext = dyn_cast<ExtensionDecl>(DC))
      dcGenericParams = ext->getGenericParams();
    else if (auto subscript = dyn_cast<SubscriptDecl>(DC))
      dcGenericParams = subscript->getGenericParams();

    while (dcGenericParams) {
      namelookup::FindLocalVal localVal(SM, Loc, Consumer);
      localVal.checkGenericParams(dcGenericParams);
      dcGenericParams = dcGenericParams->getOuterParameters();
    }

    if (ExtendedType)
      ::lookupVisibleMemberDecls(ExtendedType, Consumer, DC, LS, Reason,
                                 TypeResolver, nullptr);

    DC = DC->getParent();
    Reason = DeclVisibilityKind::MemberOfOutsideNominal;
  }

  SmallVector<ModuleDecl::ImportedModule, 8> extraImports;
  if (auto SF = dyn_cast<SourceFile>(DC)) {
    if (Loc.isValid()) {
      // Look for local variables in top-level code; normally, the parser
      // resolves these for us, but it can't do the right thing for
      // local types.
      namelookup::FindLocalVal(SM, Loc, Consumer).checkSourceFile(*SF);
    }

    if (IncludeTopLevel) {
      auto &cached = SF->getCachedVisibleDecls();
      if (!cached.empty()) {
        for (auto result : cached)
          Consumer.foundDecl(result, DeclVisibilityKind::VisibleAtTopLevel);
        return;
      }

      SF->getImportedModules(extraImports, ModuleDecl::ImportFilter::Private);
    }
  }

  if (IncludeTopLevel) {
    using namespace namelookup;
    SmallVector<ValueDecl *, 0> moduleResults;
    auto &mutableM = const_cast<ModuleDecl&>(M);
    lookupVisibleDeclsInModule(&mutableM, {}, moduleResults,
                               NLKind::UnqualifiedLookup,
                               ResolutionKind::Overloadable,
                               TypeResolver, DC, extraImports);
    for (auto result : moduleResults)
      Consumer.foundDecl(result, DeclVisibilityKind::VisibleAtTopLevel);

    if (auto SF = dyn_cast<SourceFile>(DC))
      SF->cacheVisibleDecls(std::move(moduleResults));
  }
}
コード例 #8
0
ファイル: SILGenConvert.cpp プロジェクト: lzpfmh/swift
static Substitution getSimpleSubstitution(GenericParamList &generics,
                                          CanType typeArg) {
  assert(generics.getParams().size() == 1);
  return Substitution{typeArg, {}};
}