Esempio n. 1
0
int doFormat(ArrayRef<StringRef> InputFiles) {

  for (auto InputFilename : InputFiles) {
    CompilerInvocation Invocation;
    Invocation.addInputFilename(InputFilename);
    Invocation.setModuleName("Format");
    CompilerInstance Instance;

    auto &SourceMgr = Instance.getSourceMgr();
    auto &Diags = Instance.getDiags();

    PrintingDiagnosticConsumer DiagPrinter;
    Instance.addDiagnosticConsumer(&DiagPrinter);
    if (Instance.setup(Invocation)) {
      return EXIT_FAILURE;
    }

    // First, parse the file normally and get the regular old AST.
    Instance.performParseOnly();

    auto BufferID = Instance.getInputBufferIDs().back();
    auto &SF = Instance.getMainModule()
      ->getMainSourceFile(SourceFileKind::Main);

    auto Buffer = llvm::MemoryBuffer::getFile(InputFilename);
    if (!Buffer) {
      Diags.diagnose(SourceLoc(), diag::cannot_open_file,
                     InputFilename, Buffer.getError().message());
      return EXIT_FAILURE;
    }

    auto Tokens = tokenizeWithTrivia(Invocation.getLangOptions(),
                                     SourceMgr, BufferID);

    SmallVector<Decl *, 256> FileDecls;
    SF.getTopLevelDecls(FileDecls);
    sema::Semantics Sema;
    for (auto *Decl : FileDecls) {
      if (Decl->escapedFromIfConfig()) {
        continue;
      }
      auto NewNode = transformAST(ASTNode(Decl), Sema, SourceMgr,
                                  BufferID, Tokens);
      if (NewNode.hasValue()) {
        auto Reformatted = format(NewNode.getValue());
        Reformatted.print(llvm::outs());
      }
    }
  }
  return EXIT_SUCCESS;
}
Esempio n. 2
0
int getSyntaxTree(const char *MainExecutablePath,
                  const StringRef InputFilename,
                  CompilerInstance &Instance,
                  llvm::SmallVectorImpl<syntax::Syntax> &TopLevelDecls,
                  std::vector<std::pair<RC<syntax::TokenSyntax>,
                              syntax::AbsolutePosition>> &Tokens) {
  CompilerInvocation Invocation;
  Invocation.addInputFilename(InputFilename);

  Invocation.setMainExecutablePath(
    llvm::sys::fs::getMainExecutable(MainExecutablePath,
      reinterpret_cast<void *>(&anchorForGetMainExecutable)));

  Invocation.setModuleName("Test");

  auto &SourceMgr = Instance.getSourceMgr();

  PrintingDiagnosticConsumer DiagPrinter;
  Instance.addDiagnosticConsumer(&DiagPrinter);
  if (Instance.setup(Invocation)) {
    return EXIT_FAILURE;
  }

  // First, parse the file normally and get the regular old AST.
  Instance.performParseOnly();

  if (Instance.getDiags().hadAnyError()) {
    return EXIT_FAILURE;
  }

  auto BufferID = Instance.getInputBufferIDs().back();
  SourceFile *SF = nullptr;
  for (auto Unit : Instance.getMainModule()->getFiles()) {
    SF = dyn_cast<SourceFile>(Unit);
    if (SF != nullptr) {
      break;
    }
  }
  assert(SF && "No source file");

  // Retokenize the buffer with full fidelity
  if (getTokensFromFile(BufferID, Invocation.getLangOptions(),
                        SourceMgr,
                        Instance.getDiags(), Tokens) == EXIT_FAILURE) {
    return EXIT_FAILURE;
  }

  SmallVector<Decl *, 256> FileDecls;
  SF->getTopLevelDecls(FileDecls);
  sema::Semantics Sema;
  // Convert the old ASTs to the new full-fidelity syntax tree and print
  // them out.
  for (auto *Decl : FileDecls) {
    if (Decl->escapedFromIfConfig()) {
      continue;
    }
    auto NewNode = transformAST(ASTNode(Decl), Sema, SourceMgr,
                                BufferID, Tokens);
    if (NewNode.hasValue()) {
      TopLevelDecls.push_back(NewNode.getValue());
    }
  }

  return EXIT_SUCCESS;
}
Esempio n. 3
0
std::unique_ptr<swift::CompilerInstance>
Migrator::performAFixItMigration(version::Version SwiftLanguageVersion) {
  auto InputState = States.back();
  auto InputText = InputState->getOutputText();
  auto InputBuffer =
    llvm::MemoryBuffer::getMemBufferCopy(InputText, getInputFilename());

  CompilerInvocation Invocation { StartInvocation };
  Invocation.clearInputs();
  Invocation.getLangOptions().EffectiveLanguageVersion = SwiftLanguageVersion;
  auto &LLVMArgs = Invocation.getFrontendOptions().LLVMArgs;
  auto aarch64_use_tbi = std::find(LLVMArgs.begin(), LLVMArgs.end(),
                                   "-aarch64-use-tbi");
  if (aarch64_use_tbi != LLVMArgs.end()) {
    LLVMArgs.erase(aarch64_use_tbi);
  }

  // SE-0160: When migrating, always use the Swift 3 @objc inference rules,
  // which drives warnings with the "@objc" Fix-Its.
  Invocation.getLangOptions().EnableSwift3ObjCInference = true;

  // The default behavior of the migrator, referred to as "minimal" migration
  // in SE-0160, only adds @objc Fix-Its to those cases where the Objective-C
  // entry point is explicitly used somewhere in the source code. The user
  // may also select a workflow that adds @objc for every declaration that
  // would infer @objc under the Swift 3 rules but would no longer infer
  // @objc in Swift 4.
  Invocation.getLangOptions().WarnSwift3ObjCInference =
    getMigratorOptions().KeepObjcVisibility
      ? Swift3ObjCInferenceWarnings::Complete
      : Swift3ObjCInferenceWarnings::Minimal;

  const auto &OrigFrontendOpts = StartInvocation.getFrontendOptions();

  auto InputBuffers = OrigFrontendOpts.InputBuffers;
  auto InputFilenames = OrigFrontendOpts.InputFilenames;

  for (const auto &Buffer : InputBuffers) {
    Invocation.addInputBuffer(Buffer);
  }

  for (const auto &Filename : InputFilenames) {
    Invocation.addInputFilename(Filename);
  }

  const unsigned PrimaryIndex =
    Invocation.getFrontendOptions().InputBuffers.size();

  Invocation.addInputBuffer(InputBuffer.get());
  Invocation.getFrontendOptions().PrimaryInput = {
    PrimaryIndex, SelectedInput::InputKind::Buffer
  };

  auto Instance = llvm::make_unique<swift::CompilerInstance>();
  if (Instance->setup(Invocation)) {
    return nullptr;
  }

  FixitApplyDiagnosticConsumer FixitApplyConsumer {
    InputText,
    getInputFilename(),
  };
  Instance->addDiagnosticConsumer(&FixitApplyConsumer);

  Instance->performSema();

  StringRef ResultText = InputText;
  unsigned ResultBufferID = InputState->getOutputBufferID();

  if (FixitApplyConsumer.getNumFixitsApplied() > 0) {
    SmallString<4096> Scratch;
    llvm::raw_svector_ostream OS(Scratch);
    FixitApplyConsumer.printResult(OS);
    auto ResultBuffer = llvm::MemoryBuffer::getMemBufferCopy(OS.str());
    ResultText = ResultBuffer->getBuffer();
    ResultBufferID = SrcMgr.addNewSourceBuffer(std::move(ResultBuffer));
  }

  States.push_back(MigrationState::make(MigrationKind::CompilerFixits,
                                        SrcMgr, InputState->getOutputBufferID(),
                                        ResultBufferID));
  return Instance;
}