Skip to content

Upstream lib/Migrator to Open Source #10260

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Jun 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9e690bf
migrator: Add API change data file for ios, tvos, and watchos.
nkcsgexi Apr 19, 2017
d234d96
migrator: populate migrator data from Xcode 9A126.
nkcsgexi Apr 27, 2017
8450d95
[Migrator] Integrate diff-match-patch into the Migrator pipeline
bitjammer Apr 27, 2017
3765dca
[Migrator] Fix remap printing
bitjammer Apr 27, 2017
1d05066
[migrator] Fix remap entries getting merged incorrectly in some cases…
Apr 28, 2017
005f85c
Disable test/Migrator/rdar31892850.swift
aschwaighofer Apr 28, 2017
2fe708a
Disable failing Mirgrator/wrap_optional test
aschwaighofer Apr 28, 2017
d14aa19
[test] Fix and re-enable test/Migrator/rdar31892850.swift
Apr 29, 2017
39902c9
[test] Re-enable test/Migrator/wrap-optional.swift now the fix has be…
May 2, 2017
af3a119
[migrator] Populate API change scripts using Xcode 9A131.
nkcsgexi May 2, 2017
6972e1a
[Migrator] Shift standalone removals
bitjammer May 4, 2017
1fdd80e
[Migrator] Add initial test for appkit API changes
May 12, 2017
317f691
[Migrator] Update overlay.json with config for Appkit SDK changes not…
May 12, 2017
07db112
[Migrator] Update appkit tests and overlay.json for recently added tr…
May 15, 2017
17bbad5
[test] migrator: correct a test.
nkcsgexi May 15, 2017
970127b
[Migrator] Add special-case migration for NSOpenGLGetVersion
bitjammer May 16, 2017
e12e077
[Migrator] Add specific tests for migration to Swift.abs
bitjammer May 16, 2017
d19e6a4
[Migrator] Migrator.nsopengl_openglversion.swift only runs on macOS
bitjammer May 17, 2017
6c08f80
[Migrator] Don't issue rewrites when diagnostics seen more than once
bitjammer May 18, 2017
4069d81
[Migrator] Turn off buggy line-level diff in diff-match-patch
bitjammer May 18, 2017
88c698c
[migrator] Update api diff data to xcode 9L135e
nkcsgexi May 19, 2017
eaa515b
[Migrator] Separate Float80 test to x86_64 platform
bitjammer May 22, 2017
9be5635
[migrator] Update API change data by using Xcode 9M135p.
nkcsgexi May 23, 2017
7b34ab2
[test][migrator] Add a AppKit test for changing an overriding functio…
nkcsgexi May 23, 2017
df45a9b
[Migrator] Don't add -aarch64-use-tbi twice
bitjammer May 24, 2017
807eaca
[migrator] Update API diff data by using Xcode 9M136a.
nkcsgexi May 28, 2017
a189346
[test] Fix REQUIRES lines in test
benlangmuir May 30, 2017
597d406
IDE Utils: For DeclNameViewer, we should use empty StringRef to repre…
nkcsgexi May 31, 2017
e55191f
[Migrator] Don't take redundant replacements during AST Passes
bitjammer Jun 14, 2017
c2876df
[Migrator] Migrate x.toIntMax() to Int64(x)
bitjammer May 31, 2017
fe22ae9
migrator: update API diff data again by using Xcode 9M136b since we n…
nkcsgexi May 31, 2017
b7ca27b
[Migrator] Remove remap file for primary input at the start of migration
bitjammer Jun 2, 2017
2b0e048
[Migrator] Expand tuple destructuring to support tuple input types
bitjammer Jun 13, 2017
e577ebb
migrator: update api diff data by using Xcode 9M136v.
nkcsgexi Jun 14, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,598 changes: 2,598 additions & 0 deletions include/swift/Basic/Diff.h

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions include/swift/IDE/DigesterEnums.def
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ DIFF_ITEM_KEY_KIND_INT(Index)
SPECIAL_CASE_ID(NSOpenGLSetOption)
SPECIAL_CASE_ID(NSOpenGLGetOption)
SPECIAL_CASE_ID(StaticAbsToSwiftAbs)
SPECIAL_CASE_ID(NSOpenGLGetVersion)
SPECIAL_CASE_ID(ToIntMax)
SPECIAL_CASE_ID(ToUIntMax)

#undef SPECIAL_CASE_ID
#undef DIFF_ITEM_KEY_KIND_INT
Expand Down
13 changes: 13 additions & 0 deletions include/swift/Migrator/EditorAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
#ifndef SWIFT_MIGRATOR_EDITORADAPTER_H
#define SWIFT_MIGRATOR_EDITORADAPTER_H

#include "swift/Migrator/Replacement.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Edit/Commit.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"

namespace swift {

Expand All @@ -45,6 +47,10 @@ class EditorAdapter {
/// in the `getClangFileIDForSwiftBufferID` method below.
mutable llvm::SmallDenseMap<unsigned, clang::FileID> SwiftToClangBufferMap;

/// Tracks a history of edits outside of the clang::edit::Commit collector
/// below. That doesn't handle duplicate or redundant changes.
mutable llvm::SmallSet<Replacement, 32> Replacements;

/// A running transactional collection of basic edit operations.
/// Clang uses this transaction concept to cancel a batch of edits due to
/// incompatibilities, such as those due to macro expansions, but we don't
Expand All @@ -66,6 +72,13 @@ class EditorAdapter {
clang::CharSourceRange
translateCharSourceRange(CharSourceRange SwiftSourceSourceRange) const;

/// Returns the buffer ID and absolute offset for a Swift SourceLoc.
std::pair<unsigned, unsigned> getLocInfo(swift::SourceLoc Loc) const;

/// Returns true if the replacement has already been booked. Otherwise,
/// returns false and adds it to the replacement set.
bool cacheReplacement(CharSourceRange Range, StringRef Text) const;

public:
EditorAdapter(swift::SourceManager &SwiftSrcMgr,
clang::SourceManager &ClangSrcMgr)
Expand Down
9 changes: 7 additions & 2 deletions include/swift/Migrator/FixitApplyDiagnosticConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include "swift/AST/DiagnosticConsumer.h"
#include "swift/Migrator/FixitFilter.h"
#include "swift/Migrator/Migrator.h"
#include "swift/Migrator/Replacement.h"
#include "clang/Rewrite/Core/RewriteBuffer.h"
#include "llvm/ADT/DenseSet.h"

Expand All @@ -31,6 +33,8 @@ class SourceManager;

namespace migrator {

struct Replacement;

class FixitApplyDiagnosticConsumer final
: public DiagnosticConsumer, public FixitFilter {
clang::RewriteBuffer RewriteBuf;
Expand All @@ -46,8 +50,9 @@ class FixitApplyDiagnosticConsumer final
/// determine whether to call `printResult`.
unsigned NumFixitsApplied;

/// Tracks whether a SourceLoc already got an `@objc` insertion.
llvm::SmallPtrSet<const void *, 32> AddedObjC;
/// Tracks previous replacements so we don't pump the rewrite buffer with
/// multiple equivalent replacements, which can result in weird behavior.
llvm::SmallSet<Replacement, 32> Replacements;

public:
FixitApplyDiagnosticConsumer(const StringRef Text,
Expand Down
56 changes: 56 additions & 0 deletions include/swift/Migrator/Replacement.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//===--- Replacement.h - Migrator Replacements ------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_MIGRATOR_REPLACEMENT_H
#define SWIFT_MIGRATOR_REPLACEMENT_H
namespace swift {
namespace migrator {

struct Replacement {
size_t Offset;
size_t Remove;
std::string Text;

bool isRemove() const {
return Remove > 0;
}

bool isInsert() const {
return Remove == 0 && Text.size() > 0;
}

bool isReplace() const {
return Remove > 0 && Text.size() > 0;
}

size_t endOffset() const {
if (isInsert()) {
return Offset + Text.size();
} else {
return Offset + Remove;
}
}

bool operator<(const Replacement &Other) const {
return Offset < Other.Offset;
}

bool operator==(const Replacement &Other) const {
return Offset == Other.Offset && Remove == Other.Remove &&
Text == Other.Text;
}
};

} // end namespace migrator
} // end namespace swift

#endif // SWIFT_MIGRATOR_REPLACEMENT_H
16 changes: 8 additions & 8 deletions lib/IDE/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ static const char *skipParenExpression(const char *p, const char *End) {
case ')':
done = --ParenCount == 0;
break;

case '(':
++ParenCount;
break;

case '"':
e = skipStringInCode (e, End);
break;

default:
break;
}
Expand All @@ -76,15 +76,15 @@ static const char *skipStringInCode(const char *p, const char *End) {
case '"':
done = true;
break;

case '\\':
++e;
if (e >= End)
done = true;
else if (*e == '(')
e = skipParenExpression (e, End);
break;

default:
break;
}
Expand Down Expand Up @@ -113,8 +113,8 @@ ide::isSourceInputComplete(std::unique_ptr<llvm::MemoryBuffer> MemBuf) {

SourceCompleteResult SCR;
SCR.IsComplete = !P.isInputIncomplete();
// Use the same code that was in the REPL code to track the indent level

// Use the same code that was in the REPL code to track the indent level
// for now. In the future we should get this from the Parser if possible.

CharSourceRange entireRange = SM.getRangeForBuffer(BufferID);
Expand Down Expand Up @@ -167,7 +167,7 @@ ide::isSourceInputComplete(std::unique_ptr<llvm::MemoryBuffer> MemBuf) {
if (!IndentInfos.empty())
IndentInfos.pop_back();
break;

default:
if (LineSourceStart == nullptr && !isspace(*p))
LineSourceStart = p;
Expand Down
53 changes: 53 additions & 0 deletions lib/Migrator/APIDiffMigratorPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,59 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
// Swift.abs(1.0)
Editor.replace(Call->getFn()->getSourceRange(), "Swift.abs");
return true;
case SpecialCaseId::ToUIntMax:
if (const auto *DotCall = dyn_cast<DotSyntaxCallExpr>(Call->getFn())) {
Editor.insert(DotCall->getStartLoc(), "UInt64(");
Editor.replace({ DotCall->getDotLoc(), Call->getEndLoc() }, ")");
return true;
}
return false;
case SpecialCaseId::ToIntMax:
if (const auto *DotCall = dyn_cast<DotSyntaxCallExpr>(Call->getFn())) {
Editor.insert(DotCall->getStartLoc(), "Int64(");
Editor.replace({ DotCall->getDotLoc(), Call->getEndLoc() }, ")");
return true;
}
return false;
case SpecialCaseId::NSOpenGLGetVersion: {
if (const auto *Tuple = dyn_cast<TupleExpr>(Arg)) {
if (Tuple->getNumElements() != 2) {
return false;
}

auto extractArg = [](const Expr *Arg) -> const DeclRefExpr * {
while (const auto *ICE = dyn_cast<ImplicitConversionExpr>(Arg)) {
Arg = ICE->getSubExpr();
}
if (const auto *IOE = dyn_cast<InOutExpr>(Arg)) {
return dyn_cast<DeclRefExpr>(IOE->getSubExpr());
}
return nullptr;
};

const auto *Arg0 = extractArg(Tuple->getElement(0));
const auto *Arg1 = extractArg(Tuple->getElement(1));

if (!(Arg0 && Arg1)) {
return false;
}
SmallString<256> Scratch;
llvm::raw_svector_ostream OS(Scratch);
auto StartLoc = Call->getStartLoc();
Editor.insert(StartLoc, "(");
Editor.insert(StartLoc,
SM.extractText(Lexer::getCharSourceRangeFromSourceRange(SM,
Arg0->getSourceRange())));
Editor.insert(StartLoc, ", ");
Editor.insert(StartLoc,
SM.extractText(Lexer::getCharSourceRangeFromSourceRange(SM,
Arg1->getSourceRange())));
Editor.insert(StartLoc, ") = ");
Editor.replace(Call->getSourceRange(), "NSOpenGLContext.openGLVersion");
return true;
}
return false;
}
}
}

Expand Down
54 changes: 51 additions & 3 deletions lib/Migrator/EditorAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,33 @@
#include "swift/Basic/SourceLoc.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Migrator/EditorAdapter.h"
#include "swift/Migrator/Replacement.h"
#include "swift/Parse/Lexer.h"
#include "clang/Basic/SourceManager.h"

using namespace swift;
using namespace swift::migrator;

std::pair<unsigned, unsigned>
EditorAdapter::getLocInfo(swift::SourceLoc Loc) const {
auto SwiftBufferID = SwiftSrcMgr.findBufferContainingLoc(Loc);
auto Offset = SwiftSrcMgr.getLocOffsetInBuffer(Loc, SwiftBufferID);
return { SwiftBufferID, Offset };
}

bool
EditorAdapter::cacheReplacement(CharSourceRange Range, StringRef Text) const {
unsigned SwiftBufferID, Offset;
std::tie(SwiftBufferID, Offset) = getLocInfo(Range.getStart());
Replacement R { Offset, Range.getByteLength(), Text };
if (Replacements.count(R)) {
return true;
} else {
Replacements.insert(R);
}
return false;
}

clang::FileID
EditorAdapter::getClangFileIDForSwiftBufferID(unsigned BufferID) const {
/// Check if we already have a mapping for this BufferID.
Expand All @@ -40,8 +61,8 @@ EditorAdapter::getClangFileIDForSwiftBufferID(unsigned BufferID) const {

clang::SourceLocation
EditorAdapter::translateSourceLoc(SourceLoc SwiftLoc) const {
auto SwiftBufferID = SwiftSrcMgr.findBufferContainingLoc(SwiftLoc);
auto Offset = SwiftSrcMgr.getLocOffsetInBuffer(SwiftLoc, SwiftBufferID);
unsigned SwiftBufferID, Offset;
std::tie(SwiftBufferID, Offset) = getLocInfo(SwiftLoc);

auto ClangFileID = getClangFileIDForSwiftBufferID(SwiftBufferID);
return ClangSrcMgr.getLocForStartOfFile(ClangFileID).getLocWithOffset(Offset);
Expand All @@ -67,6 +88,10 @@ bool EditorAdapter::insert(SourceLoc Loc, StringRef Text, bool AfterToken,
if (AfterToken)
Loc = Lexer::getLocForEndOfToken(SwiftSrcMgr, Loc);

if (cacheReplacement(CharSourceRange { Loc, 0 }, Text)) {
return true;
}

auto ClangLoc = translateSourceLoc(Loc);
return Edits.insert(ClangLoc, Text, /*AfterToken=*/false, BeforePreviousInsertions);
}
Expand All @@ -78,6 +103,11 @@ bool EditorAdapter::insertFromRange(SourceLoc Loc, CharSourceRange Range,
if (AfterToken)
Loc = Lexer::getLocForEndOfToken(SwiftSrcMgr, Loc);

if (cacheReplacement(CharSourceRange { Loc, 0 },
SwiftSrcMgr.extractText(Range))) {
return true;
}

auto ClangLoc = translateSourceLoc(Loc);
auto ClangCharRange = translateCharSourceRange(Range);

Expand All @@ -92,23 +122,41 @@ bool EditorAdapter::insertWrap(StringRef Before, CharSourceRange Range,
}

bool EditorAdapter::remove(CharSourceRange Range) {
if (cacheReplacement(Range, "")) {
return true;
}
auto ClangRange = translateCharSourceRange(Range);
return Edits.remove(ClangRange);
}

bool EditorAdapter::replace(CharSourceRange Range, StringRef Text) {
if (cacheReplacement(Range, Text)) {
return true;
}

auto ClangRange = translateCharSourceRange(Range);
return Edits.replace(ClangRange, Text);
}

bool EditorAdapter::replaceWithInner(CharSourceRange Range,
CharSourceRange InnerRange) {

if (cacheReplacement(Range, SwiftSrcMgr.extractText(InnerRange))) {
return true;
}
auto ClangRange = translateCharSourceRange(Range);
auto ClangInnerRange = translateCharSourceRange(InnerRange);
return Edits.replaceWithInner(ClangRange, ClangInnerRange);
}

bool EditorAdapter::replaceText(SourceLoc Loc, StringRef Text,
StringRef ReplacementText) {
StringRef ReplacementText) {
auto Range = Lexer::getCharSourceRangeFromSourceRange(SwiftSrcMgr,
{ Loc, Loc.getAdvancedLoc(Text.size())});
if (cacheReplacement(Range, Text)) {
return true;
}

auto ClangLoc = translateSourceLoc(Loc);
return Edits.replaceText(ClangLoc, Text, ReplacementText);
}
Expand Down
11 changes: 5 additions & 6 deletions lib/Migrator/FixitApplyDiagnosticConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,11 @@ handleDiagnostic(SourceManager &SM, SourceLoc Loc,
ThisBufferID);
auto Length = Fixit.getRange().getByteLength();

if (Fixit.getText().ltrim().rtrim() == "@objc") {
if (AddedObjC.count(Loc.getOpaquePointerValue())) {
return;
} else {
AddedObjC.insert(Loc.getOpaquePointerValue());
}
Replacement R { Offset, Length, Fixit.getText() };
if (Replacements.count(R)) {
return;
} else {
Replacements.insert(R);
}

RewriteBuf.ReplaceText(Offset, Length, Fixit.getText());
Expand Down
Loading