Skip to content

Commit

Permalink
Full circle.
Browse files Browse the repository at this point in the history
  • Loading branch information
johnno1962 committed Sep 30, 2020
1 parent b97fee4 commit 063a21e
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 42 deletions.
6 changes: 2 additions & 4 deletions EvalApp/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var closureText: NSTextField!

@IBAction func performEval(_: Any) {
textView.string = eval(textField.stringValue)
textView.string = swiftEvalString(contents: textField.stringValue)
}

@IBAction func closureEval(_: Any) {
if let block = eval(closureText.stringValue, (() -> ())?.self) {
block()
}
_ = swiftEval(code: closureText.stringValue+"()")
}

@objc func injected() {
Expand Down
8 changes: 4 additions & 4 deletions InjectionBundle/InjectionClient.mm
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by John Holdsworth on 06/11/2017.
// Copyright © 2017 John Holdsworth. All rights reserved.
//
// $Id: //depot/ResidentEval/InjectionBundle/InjectionClient.mm#106 $
// $Id: //depot/ResidentEval/InjectionBundle/InjectionClient.mm#108 $
//

#import "InjectionClient.h"
Expand Down Expand Up @@ -286,10 +286,10 @@ - (void)runInBackground {
NSArray<NSString *> *parts = [changed componentsSeparatedByString:@"^"];
int pathID = parts[0].intValue;
[self writeCommand:InjectionPause withString:@"5"];
if ([xprobePaths[pathID].object respondsToSelector:@selector(evalSwift:)])
[xprobePaths[pathID].object evalSwift:parts[3].stringByRemovingPercentEncoding];
if ([xprobePaths[pathID].object respondsToSelector:@selector(swiftEvalWithCode:)])
(void)[xprobePaths[pathID].object swiftEvalWithCode:parts[3].stringByRemovingPercentEncoding];
else
printf("Eval only works on NSObject subclasses\n");
printf("💉 Xprobe: Eval only works on NSObject subclasses\n");
[Xprobe writeString:[NSString stringWithFormat:@"$('BUSY%d').hidden = true; ", pathID]];
break;
}
Expand Down
18 changes: 12 additions & 6 deletions InjectionBundle/SwiftEval.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by John Holdsworth on 02/11/2017.
// Copyright © 2017 John Holdsworth. All rights reserved.
//
// $Id: //depot/ResidentEval/InjectionBundle/SwiftEval.swift#144 $
// $Id: //depot/ResidentEval/InjectionBundle/SwiftEval.swift#146 $
//
// Basic implementation of a Swift "eval()" including the
// mechanics of recompiling a class and loading the new
Expand All @@ -28,17 +28,23 @@ extension NSObject {

private static var lastEvalByClass = [String: String]()

@objc public func evalSwift(_ expression: String) {
eval("{\n\(expression)\n}", (() -> ())?.self)?()
@objc public func swiftEval(code: String) -> Bool {
if let closure = swiftEval("{\n\(code)\n}", type: (() -> ())?.self) {
closure()
return true
}
return false
}

/// eval() for String value
public func eval(_ expression: String) -> String {
return eval("\"\(expression)\"", String.self)
@objc public func swiftEvalString(contents: String) -> String {
return swiftEval("""
"\(contents)"
""", type: String.self)
}

/// eval() for value of any type
public func eval<T>(_ expression: String, _ type: T.Type) -> T {
public func swiftEval<T>(_ expression: String, type: T.Type) -> T {
let oldClass: AnyClass = object_getClass(self)!
let className = "\(oldClass)"
let extra = """
Expand Down
41 changes: 19 additions & 22 deletions InjectionIII.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
BBE490D01FB2368A003D41BB /* FileWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBE490CE1FB2368A003D41BB /* FileWatcher.swift */; };
BBE490DB1FB2C643003D41BB /* InjectionBusy.tif in Resources */ = {isa = PBXBuildFile; fileRef = BBE490D91FB2C643003D41BB /* InjectionBusy.tif */; };
BBE490DC1FB2C643003D41BB /* InjectionError.tif in Resources */ = {isa = PBXBuildFile; fileRef = BBE490DA1FB2C643003D41BB /* InjectionError.tif */; };
BBE64E5D2524D1B50049B6D4 /* SwiftEval.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB439B8A1FABA65D00B4F50B /* SwiftEval.swift */; };
BBEB704C1FD28C6F00127711 /* XcodeHash.m in Sources */ = {isa = PBXBuildFile; fileRef = BBEB704B1FD28C6F00127711 /* XcodeHash.m */; };
BD35949E21A6C5DE0020EB94 /* Vaccine.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD35949D21A6C5DE0020EB94 /* Vaccine.swift */; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -713,8 +714,7 @@
};
BB439B7A1FABA64300B4F50B = {
CreatedOnToolsVersion = 9.1;
ProvisioningStyle = Automatic;
TestTargetID = BB439B641FABA64300B4F50B;
ProvisioningStyle = Manual;
};
BB6C87C32520D0D1005AFCFC = {
CreatedOnToolsVersion = 11.5;
Expand Down Expand Up @@ -899,6 +899,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
BBE64E5D2524D1B50049B6D4 /* SwiftEval.swift in Sources */,
BB439B801FABA64300B4F50B /* SwiftEvalTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -1056,7 +1057,6 @@
SKIP_INSTALL = YES;
SWIFT_OBJC_BRIDGING_HEADER = "SwiftUISupport/SwiftUISupport-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TVOS_DEPLOYMENT_TARGET = 13.0;
WRAPPER_EXTENSION = bundle;
};
Expand Down Expand Up @@ -1092,7 +1092,6 @@
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_OBJC_BRIDGING_HEADER = "SwiftUISupport/SwiftUISupport-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TVOS_DEPLOYMENT_TARGET = 13.0;
WRAPPER_EXTENSION = bundle;
};
Expand Down Expand Up @@ -1159,7 +1158,7 @@
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
Expand Down Expand Up @@ -1220,7 +1219,7 @@
PRODUCT_NAME = macOSInjection;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
VALIDATE_PRODUCT = YES;
};
name = Release;
Expand All @@ -1229,39 +1228,42 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 9V5A8WE85E;
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = SwiftEvalTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_BUNDLE_IDENTIFIER = com.johnholdsworth.SwiftEvalTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftEval.app/SwiftEval";
};
name = Debug;
};
BB439B891FABA64300B4F50B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 9V5A8WE85E;
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = SwiftEvalTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.12;
PRODUCT_BUNDLE_IDENTIFIER = com.johnholdsworth.SwiftEvalTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 4.0;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SwiftEval.app/SwiftEval";
};
name = Release;
};
BB6C87DC2520D0D3005AFCFC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
Expand Down Expand Up @@ -1298,6 +1300,7 @@
BB6C87DD2520D0D3005AFCFC /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_LIBRARY_FOR_DISTRIBUTION = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
Expand Down Expand Up @@ -1346,7 +1349,6 @@
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = "InjectionIII/InjectionIII-Bridging-Header.h";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
Expand All @@ -1370,7 +1372,6 @@
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = "InjectionIII/InjectionIII-Bridging-Header.h";
SWIFT_VERSION = 5.0;
};
name = Release;
};
Expand All @@ -1395,7 +1396,6 @@
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OBJC_BRIDGING_HEADER = "InjectionBundle/XprobeSwift-Bridging-Header.h";
SWIFT_VERSION = 5.0;
WRAPPER_EXTENSION = bundle;
};
name = Debug;
Expand All @@ -1421,7 +1421,6 @@
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OBJC_BRIDGING_HEADER = "InjectionBundle/XprobeSwift-Bridging-Header.h";
SWIFT_VERSION = 5.0;
WRAPPER_EXTENSION = bundle;
};
name = Release;
Expand Down Expand Up @@ -1452,7 +1451,6 @@
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
Expand All @@ -1477,7 +1475,6 @@
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
SWIFT_VERSION = 5.0;
};
name = Release;
};
Expand Down
2 changes: 1 addition & 1 deletion InjectionIII/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>3980</string>
<string>4014</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.developer-tools</string>
<key>LSMinimumSystemVersion</key>
Expand Down
8 changes: 6 additions & 2 deletions InjectionIII/build_bundles.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# Created by John Holdsworth on 04/10/2019.
# Copyright © 2019 John Holdsworth. All rights reserved.
#
# $Id: //depot/ResidentEval/InjectionIII/build_bundles.sh#32 $
# $Id: //depot/ResidentEval/InjectionIII/build_bundles.sh#33 $
#

# Injection has to assume a fixed path for Xcode.app as it uses
Expand Down Expand Up @@ -37,4 +37,8 @@ build_bundle tvOS AppleTVSimulator appletvsimulator &&
"$DEVELOPER_BIN_DIR"/xcodebuild SYMROOT=$SYMROOT ARCHS="$ARCHS" PRODUCT_NAME=macOSSwiftUISupport -sdk macosx -config $CONFIGURATION -target SwiftUISupport &&
rsync -au $SYMROOT/$CONFIGURATION/macOSSwiftUISupport.bundle $SYMROOT/$CONFIGURATION-*/*.bundle "$CODESIGNING_FOLDER_PATH/Contents/Resources" &&
rsync -au $SYMROOT/$CONFIGURATION-iphonesimulator/SwiftTrace.framework/{Headers,Modules} "$CODESIGNING_FOLDER_PATH/Contents/Resources/iOSInjection.bundle/Frameworks/SwiftTrace.framework" &&
rsync -au $SYMROOT/$CONFIGURATION-appletvsimulator/SwiftTrace.framework/{Headers,Modules} "$CODESIGNING_FOLDER_PATH/Contents/Resources/tvOSInjection.bundle/Frameworks/SwiftTrace.framework"
rsync -au $SYMROOT/$CONFIGURATION-appletvsimulator/SwiftTrace.framework/{Headers,Modules} "$CODESIGNING_FOLDER_PATH/Contents/Resources/tvOSInjection.bundle/Frameworks/SwiftTrace.framework" &&
# This seems to be a bug producing .swiftinterface files.
for interface in $CODESIGNING_FOLDER_PATH/Contents/Resources/*OSInjection.bundle/Frameworks/SwiftTrace.framework/{Headers,Modules}/*/*.swiftinterface; do
sed -e s/SwiftTrace.SwiftTrace/SwiftTrace/g <$interface >/tmp/$$.swiftinterface
mv /tmp/$$.swiftinterface $interface; done
6 changes: 3 additions & 3 deletions SwiftEvalTests/SwiftEvalTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//

import XCTest
@testable import SwiftEval

class SwiftEvalTests: XCTestCase {

Expand All @@ -24,14 +23,15 @@ class SwiftEvalTests: XCTestCase {
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
XCTAssertEqual("123", eval("123"), "Basic eval test")
XCTAssertEqual("123", swiftEvalString(contents: "123"), "Basic eval test")
XCTAssertEqual(123, swiftEval("123", type: Int.self), "Basic eval test")
}

func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
XCTAssertEqual("1234", eval("1234"), "eval performance test")
XCTAssertEqual("1234", swiftEvalString(contents: "1234"), "eval performance test")
}
}

Expand Down

0 comments on commit 063a21e

Please sign in to comment.