Skip to content
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

[WIP] Adopt flag prep logic #7

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
build
*.DS_Store
!vendor/.gitignore

compile_commands.json
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ add_executable(http_server
HTTPServerMain.cpp
)

add_executable(test_driver
add_executable(tests
Logging.hpp
SwiftCompleter.hpp
SwiftCompleter.cpp
Driver.cpp
UnitTests.cpp
)

add_executable(integration_tests
Expand Down
71 changes: 0 additions & 71 deletions Driver.cpp

This file was deleted.

26 changes: 26 additions & 0 deletions Examples/iOS/Basic/Basic/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// AppDelegate.swift
// Basic
//
// Created by Jerry Marino on 5/13/17.
// Copyright © 2017 Jerry Marino. All rights reserved.
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}

func ycmdMethod() {
self.window?.sub
}
}

24 changes: 24 additions & 0 deletions Examples/iOS/Basic/Basic/ViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// ViewController.swift
// Basic
//
// Created by Jerry Marino on 5/13/17.
// Copyright © 2017 Jerry Marino. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
let delegate = UIApplication.shared.delegate as! AppDelegate
// Here we are calling a custom method on the AppDelegate
delegate.ycmd
}
}

21 changes: 21 additions & 0 deletions Examples/iOS/Basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# YCMD iOS Swift Example

This directory contains a basic example of an iOS project running under YCMD.

The example contains a project generated from Xcode, minus any unneeded files (
assets, xcodeproj, etc )

It's a simple iOS app and ViewController.swift depends on AppDelegate.swift.

It should serve as a base case so that we can make sure symbols are correctly
loading for people from the iOS SDK and external files.

These abilities are mostly dependent on a correct Compilation Database.

The Compilation Database is a template which is written in test setup. It must
be in the root directory of the examples. This template was generated from a
build of these files under xcodebuild, with the following manual changes:

- replace the source root with __SRCROOT__
- remove 10.3 version requirement
- strip out flags that pass missing build artifacts
12 changes: 12 additions & 0 deletions Examples/iOS/Basic/compile_commands.json.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[
{
"directory": "__SRCROOT__",
"command": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -primary-file __SRCROOT__/Basic/ViewController.swift __SRCROOT__/Basic/AppDelegate.swift -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk -enable-testing -g -serialize-debugging-options -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/swift-overrides.hmap -Xcc -iquote -Xcc /Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/Basic-generated-files.hmap -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/Basic-own-target-headers.hmap -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/Basic-all-target-headers.hmap -Xcc -iquote -Xcc /Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/Basic-project-headers.hmap -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/DerivedSources/x86_64 -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/DerivedSources -Xcc -DDEBUG=1 -Xcc -working-directory__SRCROOT__ -Onone -module-name Basic -o /Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/Objects-normal/x86_64/ViewController.o",
"file": "__SRCROOT__/Basic/ViewController.swift"
},
{
"directory": "__SRCROOT__",
"command": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c __SRCROOT__/Basic/ViewController.swift -primary-file __SRCROOT__/Basic/AppDelegate.swift -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk -enable-testing -g -serialize-debugging-options -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/swift-overrides.hmap -Xcc -iquote -Xcc /Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/Basic-generated-files.hmap -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/Basic-own-target-headers.hmap -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/Basic-all-target-headers.hmap -Xcc -iquote -Xcc /Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/Basic-project-headers.hmap -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Products/Debug-iphonesimulator/include -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/DerivedSources/x86_64 -Xcc -I/Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/DerivedSources -Xcc -DDEBUG=1 -Xcc -working-directory__SRCROOT__ -Onone -module-name Basic -o /Users/fakeuser/Library/Developer/Xcode/DerivedData/Basic-dcvyhoqxsulylretnajwiqnkngaj/Build/Intermediates/Basic.build/Debug-iphonesimulator/Basic.build/Objects-normal/x86_64/AppDelegate.o",
"file": "__SRCROOT__/Basic/AppDelegate.swift"
}
]
93 changes: 91 additions & 2 deletions SwiftCompleter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#import <future>
#import <iostream>
#import <map>
#import <set>
#import <sourcekitd/sourcekitd.h>
#import <sstream>
#import <string>
Expand Down Expand Up @@ -449,7 +450,7 @@ const std::string SwiftCompleter::CandidatesForLocationInFile(
ctx.line = line;
ctx.column = column;
ctx.unsavedFiles = unsavedFiles;
ctx.flags = flags;
ctx.flags = FlagsForCompileCommand(flags);

SourceKitService sktService(_logger.level());
char *response = NULL;
Expand All @@ -458,14 +459,30 @@ const std::string SwiftCompleter::CandidatesForLocationInFile(
return response;
}

// Transform completion flags into diagnostic flags
auto DiagnosticFlagsFromFlags(std::string filename,
std::vector<std::string> flags) {
std::vector<std::string> outputFlags;
// Skip the file - I'm not 100% sure why we need this but it will output
// weird warnings if not.
for (auto &f : flags) {
if (f == filename) {
continue;
}
outputFlags.push_back(f);
}
return outputFlags;
}

const std::string
SwiftCompleter::DiagnosticsForFile(const std::string &filename,
const std::vector<UnsavedFile> &unsavedFiles,
const std::vector<std::string> &flags) {
CompletionContext ctx;
ctx.sourceFilename = filename;
ctx.unsavedFiles = unsavedFiles;
ctx.flags = flags;
auto completionFlags = FlagsForCompileCommand(flags);
ctx.flags = DiagnosticFlagsFromFlags(filename, completionFlags);
ctx.line = 0;
ctx.column = 0;

Expand All @@ -483,3 +500,75 @@ SwiftCompleter::DiagnosticsForFile(const std::string &filename,
return semaresult;
}
} // namespace ssvim
// namespace ssvim

#pragma mark - Command Preparation Logic

// Basic flag blacklist is a list of flags that cannot be included in a
// CompilerInvocation for completion.
//
// These flags are a pair in the form
// __FLAG__ Optional(__VALUE__)
//
// For example -c sometimes has a value after it.
//
// Only skip __VALUE__ when it doesn't start with -.

auto FlagStartToken = '-';
std::set<std::string> BasicFlagBlacklist{"-c",
"-MP",
"-MD",
"-MMD",
"--fcolor-diagnostics",
"-emit-reference-dependencies-path",
"-emit-dependencies-path",
"-emit-module-path",
"-serialize-diagnostics-path",
"-emit-module-doc-path",
"-frontend",
"-o"};

// These flags may specified as pair of the form
// __FLAG__ __VALUE__
//
// Unconditionally exclude flags in this blacklist and the next value

std::set<std::string> PairedFlagBlacklist{"-Xcc"};

// Take a raw split command and output completion flags
std::vector<std::string>
ssvim::FlagsForCompileCommand(std::vector<std::string> flags) {
if (flags.size() == 0) {
return flags;
}

std::vector<std::string> outFlags;

// Skip the first flag if needed
// Assume that someone will be using a swift compiler with an absolute path
// and strip it off if so. All compile commands should be formed this way,
// but some old test code uses it, so leave it for now.
auto isCompilerBinary = flags.at(0)[0] == '/';
unsigned long i = isCompilerBinary ? 1 : 0;
auto length = flags.size();
while (i < length) {
auto flag = flags.at(i);
if (PairedFlagBlacklist.find(flag) != PairedFlagBlacklist.end()) {
i = i + 1;
} else if (BasicFlagBlacklist.find(flag) != BasicFlagBlacklist.end()) {
auto nextIdx = i + 1;

// Skip the pair (FLAG, VALUE) when the next value isn't
// another flag.
if (nextIdx < length) {
if (flags[nextIdx][0] != FlagStartToken) {
i = i + 1;
}
}
} else {
outFlags.push_back(flag);
}
i = i + 1;
}
return outFlags;
}
6 changes: 6 additions & 0 deletions SwiftCompleter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,10 @@ class SwiftCompleter {
const std::vector<UnsavedFile> &unsavedFiles,
const std::vector<std::string> &flags);
};

#pragma mark - Testing

extern std::vector<std::string>
FlagsForCompileCommand(std::vector<std::string> flags);

} // namespace ssvim
Loading