mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-27 05:57:04 +00:00
New: --no-colors option for nib2cib.
Previously error messages would always be colorized, which doesn't work well if you are piping the output. Passing --no-colors turns off all colors in the output.
This commit is contained in:
+1269
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,584 @@
|
||||
/*
|
||||
* parser.j
|
||||
*
|
||||
* Created by Francisco Tolmasky.
|
||||
* Modified by Antoine Mercadal, with great help of Martin Carlberg
|
||||
* Copyright 2008-2013, 280 North, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@import <Foundation/Foundation.j>
|
||||
|
||||
var FILE = require("file"),
|
||||
OS = require("os");
|
||||
|
||||
// Debug function to print some JS objects
|
||||
function dump(obj)
|
||||
{
|
||||
print(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
function raise(pos, message)
|
||||
{
|
||||
var syntaxError = new SyntaxError(message);
|
||||
syntaxError.line = pos.line;
|
||||
syntaxError.column = pos.column;
|
||||
syntaxError.lineStart = pos.lineStart;
|
||||
syntaxError.lineEnd = pos.lineEnd;
|
||||
|
||||
throw syntaxError;
|
||||
}
|
||||
|
||||
var hasWarnings = false,
|
||||
xcc = ObjectiveJ.acorn.walk.make(
|
||||
{
|
||||
ClassDeclarationStatement: function(node, st, c)
|
||||
{
|
||||
if (node.categoryname)
|
||||
{
|
||||
print("Line " + node.loc.start.line + ", " + node.loc.source);
|
||||
print("Categories are not supported yet. Ignoring it.");
|
||||
hasWarnings = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var className = node.classname.name,
|
||||
superclassname = node.superclassname.name,
|
||||
declaredOutletsName = [],
|
||||
classInfo = {
|
||||
"name": className,
|
||||
"superClass": superclassname,
|
||||
"outlets": [],
|
||||
"actions": [],
|
||||
"actionNames": []
|
||||
};
|
||||
|
||||
if (node.ivardeclarations)
|
||||
{
|
||||
for (var i = 0; i < node.ivardeclarations.length; ++i)
|
||||
{
|
||||
var ivarDecl = node.ivardeclarations[i],
|
||||
ivarType = ivarDecl.ivartype ? ivarDecl.ivartype.name : null,
|
||||
ivarName = ivarDecl.id.name,
|
||||
ivarHasOutlet = ivarDecl.outlet ? "@outlet" : null;
|
||||
|
||||
if (ivarHasOutlet)
|
||||
{
|
||||
if (declaredOutletsName.indexOf(ivarName) !== -1)
|
||||
raise(ivarDecl.loc.start, "Outlet named '" + ivarName + "' is declared multiple times.");
|
||||
|
||||
declaredOutletsName.push(ivarName);
|
||||
classInfo.outlets.push({"type": ivarType, "name": ivarName});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
st.push(classInfo)
|
||||
|
||||
for (var i = 0; i < node.body.length; ++i)
|
||||
c(node.body[i], classInfo, "Statement");
|
||||
},
|
||||
|
||||
MethodDeclarationStatement: function(node, st, c)
|
||||
{
|
||||
var selectors = node.selectors,
|
||||
arguments = node.arguments,
|
||||
methodReturnType = [node.returntype ? node.returntype.name : "id"],
|
||||
methodHasAction = node.action ? "IBAction" : null,
|
||||
selector = selectors[0].name,
|
||||
actionInformations = {"name": selector, "arguments":[]};
|
||||
|
||||
if (methodHasAction && arguments.length == 1)
|
||||
{
|
||||
if (st.actionNames.indexOf(selector) !== -1)
|
||||
raise(node.loc.start, "Action named '" + selector + "' is declared multiple times.");
|
||||
|
||||
st.actionNames.push(selector);
|
||||
|
||||
for (var i = 0; i < arguments.length; i++)
|
||||
{
|
||||
var argument = arguments[i],
|
||||
argumentName = argument.identifier.name,
|
||||
argumentType = argument.type ? argument.type.name : null;
|
||||
|
||||
actionInformations.arguments.push({"type": argumentType, "name": argumentName});
|
||||
}
|
||||
|
||||
st.actions.push(actionInformations)
|
||||
}
|
||||
else if (methodHasAction)
|
||||
raise(node.loc.start, "Method '" + selector + "' is an action but has more than one parameter.");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function compile(node, state, visitor)
|
||||
{
|
||||
function c(node, st, override)
|
||||
{
|
||||
visitor[override || node.type](node, st, c);
|
||||
}
|
||||
|
||||
c(node, state);
|
||||
};
|
||||
|
||||
|
||||
function main(args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileURL = new CFURL(args[1]),
|
||||
outputBaseURL = new CFURL(args[2]),
|
||||
outputHeaderURL = new CFURL(outputBaseURL.path() + ".h"),
|
||||
outputSourceURL = new CFURL(outputBaseURL.path() + ".m"),
|
||||
source = FILE.read(fileURL, { charset: "UTF-8" }),
|
||||
flags = ObjectiveJ.Preprocessor.Flags.IncludeDebugSymbols | ObjectiveJ.Preprocessor.Flags.IncludeTypeSignatures,
|
||||
tokens = ObjectiveJ.acorn.parse(source, { locations:true, sourceFile:fileURL.path() }),
|
||||
classesInformation = [],
|
||||
ObjectiveCSource = "",
|
||||
ObjectiveCHeader = "";
|
||||
|
||||
compile(tokens, classesInformation, xcc);
|
||||
|
||||
// dump(classesInformation)
|
||||
|
||||
ObjectiveCHeader +=
|
||||
"#import <Foundation/Foundation.h>\n" +
|
||||
"#import <Cocoa/Cocoa.h>\n" +
|
||||
"#import \"xcc_general_include.h\"\n\n";
|
||||
|
||||
ObjectiveCSource += "#import \"" + outputHeaderURL.lastPathComponent() + "\"\n\n";
|
||||
|
||||
// Traverse each found classes
|
||||
classesInformation.forEach(function(aClass)
|
||||
{
|
||||
// add new class definition
|
||||
ObjectiveCHeader += "@interface " + aClass.name + " : " + NSCompatibleClassName(aClass.superClass) + "\n\n";
|
||||
|
||||
// Add each outlets in header
|
||||
aClass.outlets.forEach(function(anOutlet)
|
||||
{
|
||||
ObjectiveCHeader += "@property (assign) IBOutlet " + NSCompatibleClassName(anOutlet.type, YES) + " " + anOutlet.name + ";\n";
|
||||
});
|
||||
|
||||
ObjectiveCHeader += "\n";
|
||||
|
||||
// Add each actions in header
|
||||
aClass.actions.forEach(function(anAction)
|
||||
{
|
||||
ObjectiveCHeader += "- (IBAction)" + anAction.name + ":(" + anAction.arguments[0].type + ")" + anAction.arguments[0].name + ";\n";
|
||||
});
|
||||
|
||||
ObjectiveCHeader += "\n@end\n\n\n";
|
||||
|
||||
// fill up the implementation file
|
||||
ObjectiveCSource += "@implementation " + aClass.name + "\n@end\n\n";
|
||||
});
|
||||
|
||||
// write files
|
||||
if (ObjectiveCSource.length)
|
||||
FILE.write(outputSourceURL, ObjectiveCSource, { charset:"UTF-8" });
|
||||
|
||||
if (ObjectiveCHeader.length)
|
||||
FILE.write(outputHeaderURL, ObjectiveCHeader, { charset:"UTF-8" });
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
if (e instanceof SyntaxError)
|
||||
print("Line " + e.line + ", " + fileURL.path());
|
||||
|
||||
print(e.name + ": " + e.message);
|
||||
OS.exit(1);
|
||||
}
|
||||
|
||||
if (hasWarnings)
|
||||
OS.exit(2);
|
||||
}
|
||||
|
||||
function NSCompatibleClassName(aClassName, asPointer)
|
||||
{
|
||||
if (aClassName === "var" || aClassName === "id")
|
||||
return "id";
|
||||
|
||||
var prefix = aClassName.substr(0, 2),
|
||||
asterisk = asPointer ? "*" : "";
|
||||
|
||||
if (prefix !== "CP")
|
||||
return aClassName + asterisk;
|
||||
|
||||
var NSClassName = "NS" + aClassName.substr(2);
|
||||
|
||||
if (NSClasses[NSClassName])
|
||||
return NSClassName + asterisk;
|
||||
|
||||
if (ReplacementClasses[aClassName])
|
||||
return ReplacementClasses[aClassName] + asterisk;
|
||||
|
||||
return aClassName + asterisk;
|
||||
}
|
||||
|
||||
var ReplacementClasses = {
|
||||
"CPWebView": "WebView",
|
||||
"CPRadio": "NSButtonCell",
|
||||
"CPRadioGroup": "NSMatrix"
|
||||
};
|
||||
|
||||
var NSClasses = {
|
||||
"NSAffineTransform" : YES,
|
||||
"NSAppleEventDescriptor" : YES,
|
||||
"NSAppleEventManager" : YES,
|
||||
"NSAppleScript" : YES,
|
||||
"NSArchiver" : YES,
|
||||
"NSArray" : YES,
|
||||
"NSAssertionHandler" : YES,
|
||||
"NSAttributedString" : YES,
|
||||
"NSAutoreleasePool" : YES,
|
||||
"NSBlockOperation" : YES,
|
||||
"NSBundle" : YES,
|
||||
"NSCache" : YES,
|
||||
"NSCachedURLResponse" : YES,
|
||||
"NSCalendar" : YES,
|
||||
"NSCharacterSet" : YES,
|
||||
"NSClassDescription" : YES,
|
||||
"NSCloneCommand" : YES,
|
||||
"NSCloseCommand" : YES,
|
||||
"NSCoder" : YES,
|
||||
"NSComparisonPredicate" : YES,
|
||||
"NSCompoundPredicate" : YES,
|
||||
"NSCondition" : YES,
|
||||
"NSConditionLock" : YES,
|
||||
"NSConnection" : YES,
|
||||
"NSCountCommand" : YES,
|
||||
"NSCountedSet" : YES,
|
||||
"NSCreateCommand" : YES,
|
||||
"NSData" : YES,
|
||||
"NSDate" : YES,
|
||||
"NSDateComponents" : YES,
|
||||
"NSDateFormatter" : YES,
|
||||
"NSDecimalNumber" : YES,
|
||||
"NSDecimalNumberHandler" : YES,
|
||||
"NSDeleteCommand" : YES,
|
||||
"NSDeserializer" : YES,
|
||||
"NSDictionary" : YES,
|
||||
"NSDirectoryEnumerator" : YES,
|
||||
"NSDistantObject" : YES,
|
||||
"NSDistantObjectRequest" : YES,
|
||||
"NSDistributedLock" : YES,
|
||||
"NSDistributedNotificationCenter" : YES,
|
||||
"NSEnumerator" : YES,
|
||||
"NSError" : YES,
|
||||
"NSException" : YES,
|
||||
"NSExistsCommand" : YES,
|
||||
"NSExpression" : YES,
|
||||
"NSFileHandle" : YES,
|
||||
"NSFileManager" : YES,
|
||||
"NSFileWrapper" : YES,
|
||||
"NSFormatter" : YES,
|
||||
"NSGarbageCollector" : YES,
|
||||
"NSGetCommand" : YES,
|
||||
"NSHashTable" : YES,
|
||||
"NSHost" : YES,
|
||||
"NSHTTPCookie" : YES,
|
||||
"NSHTTPCookieStorage" : YES,
|
||||
"NSHTTPURLResponse" : YES,
|
||||
"NSIndexPath" : YES,
|
||||
"NSIndexSet" : YES,
|
||||
"NSIndexSpecifier" : YES,
|
||||
"NSInputStream" : YES,
|
||||
"NSInvocation" : YES,
|
||||
"NSInvocationOperation" : YES,
|
||||
"NSKeyedArchiver" : YES,
|
||||
"NSKeyedUnarchiver" : YES,
|
||||
"NSLocale" : YES,
|
||||
"NSLock" : YES,
|
||||
"NSLogicalTest" : YES,
|
||||
"NSMachBootstrapServer" : YES,
|
||||
"NSMachPort" : YES,
|
||||
"NSMapTable" : YES,
|
||||
"NSMessagePort" : YES,
|
||||
"NSMessagePortNameServer" : YES,
|
||||
"NSMetadataItem" : YES,
|
||||
"NSMetadataQuery" : YES,
|
||||
"NSMetadataQueryAttributeValueTuple" : YES,
|
||||
"NSMetadataQueryResultGroup" : YES,
|
||||
"NSMethodSignature" : YES,
|
||||
"NSMiddleSpecifier" : YES,
|
||||
"NSMoveCommand" : YES,
|
||||
"NSMutableArray" : YES,
|
||||
"NSMutableAttributedString" : YES,
|
||||
"NSMutableCharacterSet" : YES,
|
||||
"NSMutableData" : YES,
|
||||
"NSMutableDictionary" : YES,
|
||||
"NSMutableIndexSet" : YES,
|
||||
"NSMutableSet" : YES,
|
||||
"NSMutableString" : YES,
|
||||
"NSMutableURLRequest" : YES,
|
||||
"NSNameSpecifier" : YES,
|
||||
"NSNetService" : YES,
|
||||
"NSNetServiceBrowser" : YES,
|
||||
"NSNotification" : YES,
|
||||
"NSNotificationCenter" : YES,
|
||||
"NSNotificationQueue" : YES,
|
||||
"NSNull" : YES,
|
||||
"NSNumber" : YES,
|
||||
"NSNumberFormatter" : YES,
|
||||
"NSObject" : YES,
|
||||
"NSOperation" : YES,
|
||||
"NSOperationQueue" : YES,
|
||||
"NSOrthography" : YES,
|
||||
"NSOutputStream" : YES,
|
||||
"NSPipe" : YES,
|
||||
"NSPointerArray" : YES,
|
||||
"NSPointerFunctions" : YES,
|
||||
"NSPort" : YES,
|
||||
"NSPortCoder" : YES,
|
||||
"NSPortMessage" : YES,
|
||||
"NSPortNameServer" : YES,
|
||||
"NSPositionalSpecifier" : YES,
|
||||
"NSPredicate" : YES,
|
||||
"NSProcessInfo" : YES,
|
||||
"NSPropertyListSerialization" : YES,
|
||||
"NSPropertySpecifier" : YES,
|
||||
"NSProtocolChecker" : YES,
|
||||
"NSProxy" : YES,
|
||||
"NSPurgeableData" : YES,
|
||||
"NSQuitCommand" : YES,
|
||||
"NSRandomSpecifier" : YES,
|
||||
"NSRangeSpecifier" : YES,
|
||||
"NSRecursiveLock" : YES,
|
||||
"NSRelativeSpecifier" : YES,
|
||||
"NSRunLoop" : YES,
|
||||
"NSScanner" : YES,
|
||||
"NSScriptClassDescription" : YES,
|
||||
"NSScriptCoercionHandler" : YES,
|
||||
"NSScriptCommand" : YES,
|
||||
"NSScriptCommandDescription" : YES,
|
||||
"NSScriptExecutionContext" : YES,
|
||||
"NSScriptObjectSpecifier" : YES,
|
||||
"NSScriptSuiteRegistry" : YES,
|
||||
"NSScriptWhoseTest" : YES,
|
||||
"NSSerializer" : YES,
|
||||
"NSSet" : YES,
|
||||
"NSSetCommand" : YES,
|
||||
"NSSocketPort" : YES,
|
||||
"NSSocketPortNameServer" : YES,
|
||||
"NSSortDescriptor" : YES,
|
||||
"NSSpecifierTest" : YES,
|
||||
"NSSpellServer" : YES,
|
||||
"NSStream" : YES,
|
||||
"NSString" : YES,
|
||||
"NSTask" : YES,
|
||||
"NSTextCheckingResult" : YES,
|
||||
"NSThread" : YES,
|
||||
"NSTimer" : YES,
|
||||
"NSTimeZone" : YES,
|
||||
"NSUnarchiver" : YES,
|
||||
"NSUndoManager" : YES,
|
||||
"NSUniqueIDSpecifier" : YES,
|
||||
"NSURL" : YES,
|
||||
"NSURLAuthenticationChallenge" : YES,
|
||||
"NSURLCache" : YES,
|
||||
"NSURLConnection" : YES,
|
||||
"NSURLCredential" : YES,
|
||||
"NSURLCredentialStorage" : YES,
|
||||
"NSURLDownload" : YES,
|
||||
"NSURLHandle" : YES,
|
||||
"NSURLProtectionSpace" : YES,
|
||||
"NSURLProtocol" : YES,
|
||||
"NSURLRequest" : YES,
|
||||
"NSURLResponse" : YES,
|
||||
"NSUserDefaults" : YES,
|
||||
"NSValue" : YES,
|
||||
"NSValueTransformer" : YES,
|
||||
"NSWhoseSpecifier" : YES,
|
||||
"NSXMLDocument" : YES,
|
||||
"NSXMLDTD" : YES,
|
||||
"NSXMLDTDNode" : YES,
|
||||
"NSXMLElement" : YES,
|
||||
"NSXMLNode" : YES,
|
||||
"NSXMLParser" : YES,
|
||||
"NSActionCell" : YES,
|
||||
"NSAffineTransform Additions" : YES,
|
||||
"NSAlert" : YES,
|
||||
"NSAnimation" : YES,
|
||||
"NSAnimationContext" : YES,
|
||||
"NSAppleScript Additions" : YES,
|
||||
"NSApplication" : YES,
|
||||
"NSArrayController" : YES,
|
||||
"NSATSTypesetter" : YES,
|
||||
"NSAttributedString Application Kit Additions" : YES,
|
||||
"NSBezierPath" : YES,
|
||||
"NSBitmapImageRep" : YES,
|
||||
"NSBox" : YES,
|
||||
"NSBrowser" : YES,
|
||||
"NSBrowserCell" : YES,
|
||||
"NSBundle Additions" : YES,
|
||||
"NSButton" : YES,
|
||||
"NSButtonCell" : YES,
|
||||
"NSCachedImageRep" : YES,
|
||||
"NSCell" : YES,
|
||||
"NSCIImageRep" : YES,
|
||||
"NSClipView" : YES,
|
||||
"NSCoder Application Kit Additions" : YES,
|
||||
"NSCollectionView" : YES,
|
||||
"NSCollectionViewItem" : YES,
|
||||
"NSColor" : YES,
|
||||
"NSColorList" : YES,
|
||||
"NSColorPanel" : YES,
|
||||
"NSColorPicker" : YES,
|
||||
"NSColorSpace" : YES,
|
||||
"NSColorWell" : YES,
|
||||
"NSComboBox" : YES,
|
||||
"NSComboBoxCell" : YES,
|
||||
"NSControl" : YES,
|
||||
"NSController" : YES,
|
||||
"NSCursor" : YES,
|
||||
"NSCustomImageRep" : YES,
|
||||
"NSDatePicker" : YES,
|
||||
"NSDatePickerCell" : YES,
|
||||
"NSDictionaryController" : YES,
|
||||
"NSDockTile" : YES,
|
||||
"NSDocument" : YES,
|
||||
"NSDocumentController" : YES,
|
||||
"NSDrawer" : YES,
|
||||
"NSEPSImageRep" : YES,
|
||||
"NSEvent" : YES,
|
||||
"NSFileWrapper" : YES,
|
||||
"NSFont" : YES,
|
||||
"NSFontDescriptor" : YES,
|
||||
"NSFontManager" : YES,
|
||||
"NSFontPanel" : YES,
|
||||
"NSForm" : YES,
|
||||
"NSFormCell" : YES,
|
||||
"NSGlyphGenerator" : YES,
|
||||
"NSGlyphInfo" : YES,
|
||||
"NSGradient" : YES,
|
||||
"NSGraphicsContext" : YES,
|
||||
"NSHelpManager" : YES,
|
||||
"NSImage" : YES,
|
||||
"NSImageCell" : YES,
|
||||
"NSImageRep" : YES,
|
||||
"NSImageView" : YES,
|
||||
"NSLayoutManager" : YES,
|
||||
"NSLevelIndicator" : YES,
|
||||
"NSLevelIndicatorCell" : YES,
|
||||
"NSMatrix" : YES,
|
||||
"NSMenu" : YES,
|
||||
"NSMenuItem" : YES,
|
||||
"NSMenuItemCell" : YES,
|
||||
"NSMenuView" : YES,
|
||||
"NSMutableAttributedString Additions" : YES,
|
||||
"NSMutableParagraphStyle" : YES,
|
||||
"NSNib" : YES,
|
||||
"NSNibConnector" : YES,
|
||||
"NSNibControlConnector" : YES,
|
||||
"NSNibOutletConnector" : YES,
|
||||
"NSObjectController" : YES,
|
||||
"NSOpenGLContext" : YES,
|
||||
"NSOpenGLLayer" : YES,
|
||||
"NSOpenGLPixelBuffer" : YES,
|
||||
"NSOpenGLPixelFormat" : YES,
|
||||
"NSOpenGLView" : YES,
|
||||
"NSOpenPanel" : YES,
|
||||
"NSOutlineView" : YES,
|
||||
"NSPageLayout" : YES,
|
||||
"NSPanel" : YES,
|
||||
"NSParagraphStyle" : YES,
|
||||
"NSPasteboard" : YES,
|
||||
"NSPasteboardItem" : YES,
|
||||
"NSPathCell" : YES,
|
||||
"NSPathComponentCell" : YES,
|
||||
"NSPathControl" : YES,
|
||||
"NSPDFImageRep" : YES,
|
||||
"NSPersistentDocument" : YES,
|
||||
"NSPICTImageRep" : YES,
|
||||
"NSPopUpButton" : YES,
|
||||
"NSPopUpButtonCell" : YES,
|
||||
"NSPredicateEditor" : YES,
|
||||
"NSPredicateEditorRowTemplate" : YES,
|
||||
"NSPrinter" : YES,
|
||||
"NSPrintInfo" : YES,
|
||||
"NSPrintOperation" : YES,
|
||||
"NSPrintPanel" : YES,
|
||||
"NSProgressIndicator" : YES,
|
||||
"NSResponder" : YES,
|
||||
"NSRuleEditor" : YES,
|
||||
"NSRulerMarker" : YES,
|
||||
"NSRulerView" : YES,
|
||||
"NSRunningApplication" : YES,
|
||||
"NSSavePanel" : YES,
|
||||
"NSScreen" : YES,
|
||||
"NSScroller" : YES,
|
||||
"NSScrollView" : YES,
|
||||
"NSSearchField" : YES,
|
||||
"NSSearchFieldCell" : YES,
|
||||
"NSSecureTextField" : YES,
|
||||
"NSSecureTextFieldCell" : YES,
|
||||
"NSSegmentedCell" : YES,
|
||||
"NSSegmentedControl" : YES,
|
||||
"NSShadow" : YES,
|
||||
"NSSlider" : YES,
|
||||
"NSSliderCell" : YES,
|
||||
"NSSound" : YES,
|
||||
"NSSpeechRecognizer" : YES,
|
||||
"NSSpeechSynthesizer" : YES,
|
||||
"NSSpellChecker" : YES,
|
||||
"NSSplitView" : YES,
|
||||
"NSStatusBar" : YES,
|
||||
"NSStatusItem" : YES,
|
||||
"NSStepper" : YES,
|
||||
"NSStepperCell" : YES,
|
||||
"NSString Application Kit Additions" : YES,
|
||||
"NSTableColumn" : YES,
|
||||
"NSTableHeaderCell" : YES,
|
||||
"NSTableHeaderView" : YES,
|
||||
"NSTableView" : YES,
|
||||
"NSTabView" : YES,
|
||||
"NSTabViewItem" : YES,
|
||||
"NSText" : YES,
|
||||
"NSTextAttachment" : YES,
|
||||
"NSTextAttachmentCell" : YES,
|
||||
"NSTextBlock" : YES,
|
||||
"NSTextContainer" : YES,
|
||||
"NSTextField" : YES,
|
||||
"NSTextFieldCell" : YES,
|
||||
"NSTextInputContext" : YES,
|
||||
"NSTextList" : YES,
|
||||
"NSTextStorage" : YES,
|
||||
"NSTextTab" : YES,
|
||||
"NSTextTable" : YES,
|
||||
"NSTextTableBlock" : YES,
|
||||
"NSTextView" : YES,
|
||||
"NSTokenField" : YES,
|
||||
"NSTokenFieldCell" : YES,
|
||||
"NSToolbar" : YES,
|
||||
"NSToolbarItem" : YES,
|
||||
"NSToolbarItemGroup" : YES,
|
||||
"NSTouch" : YES,
|
||||
"NSTrackingArea" : YES,
|
||||
"NSTreeController" : YES,
|
||||
"NSTreeNode" : YES,
|
||||
"NSTypesetter" : YES,
|
||||
"NSURL Additions" : YES,
|
||||
"NSUserDefaultsController" : YES,
|
||||
"NSView" : YES,
|
||||
"NSViewAnimation" : YES,
|
||||
"NSViewController" : YES,
|
||||
"NSWindow" : YES,
|
||||
"NSWindowController" : YES,
|
||||
"NSWorkspace" : YES,
|
||||
"NSPopover": YES
|
||||
};
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
from mod_pbxproj import XcodeProject
|
||||
|
||||
XCODESUPPORTFOLDER = ".XcodeSupport"
|
||||
SLASH_REPLACEMENT = u"∕" # DIVISION SLASH Unicode U+2215
|
||||
STRING_RE = re.compile(ur"^\s*<string>(.*)</string>\s*$", re.MULTILINE)
|
||||
FRAMEWORKS_RE = re.compile(ur"^(.+/Frameworks/Debug/([^/]+))/.+$")
|
||||
|
||||
|
||||
def update_general_include(project, projectBasePath):
|
||||
xcc_general_include_file = os.path.join(projectBasePath, XCODESUPPORTFOLDER, u"xcc_general_include.h")
|
||||
content = u""
|
||||
|
||||
for file in os.listdir(os.path.join(projectBasePath, XCODESUPPORTFOLDER)):
|
||||
if file.endswith(".h"):
|
||||
content += u'#include "{0}"\n'.format(os.path.basename(unicode(file)))
|
||||
|
||||
f = open(xcc_general_include_file, "w")
|
||||
f.write(content.encode("utf-8"))
|
||||
f.close()
|
||||
|
||||
if len(project.get_files_by_os_path(os.path.join(XCODESUPPORTFOLDER, os.path.basename(xcc_general_include_file)))) == 0:
|
||||
project.add_file(xcc_general_include_file, parent=shadowGroup)
|
||||
|
||||
def add_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationFilePath, sourcePath, projectBasePath):
|
||||
project.add_file(shadowHeaderPath, parent=shadowGroup)
|
||||
project.add_file(shadowImplementationFilePath, parent=shadowGroup)
|
||||
|
||||
if sourcePath in project.get_files_by_os_path(os.path.relpath(sourcePath, projectBasePath)):
|
||||
return
|
||||
|
||||
project.add_file(sourcePath, parent=sourceGroup)
|
||||
|
||||
def remove_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationFilePath, sourcePath, projectBasePath):
|
||||
project.remove_file(os.path.join(XCODESUPPORTFOLDER, os.path.basename(shadowHeaderPath)), parent=shadowGroup)
|
||||
project.remove_file(os.path.join(XCODESUPPORTFOLDER, os.path.basename(shadowImplementationFilePath)), parent=shadowGroup)
|
||||
project.remove_file(os.path.relpath(sourcePath, projectBasePath), parent=sourceGroup)
|
||||
|
||||
def xml_converter(matchObj):
|
||||
return "<string>{0}</string>".format(matchObj.group(1).encode('ascii', 'xmlcharrefreplace'))
|
||||
|
||||
def convert_unicode_to_xml(path):
|
||||
"""
|
||||
mod_pbxproj writes unicode data as utf-8, but since it's an xml plist
|
||||
all non-ascii characters should be converted to xml character references.
|
||||
So we do that as a post-processing phase.
|
||||
"""
|
||||
with open(path, 'rb') as f:
|
||||
content = f.read().decode('utf-8')
|
||||
|
||||
with open(path, "wb") as f:
|
||||
content = STRING_RE.sub(xml_converter, content)
|
||||
f.write(content)
|
||||
|
||||
def add_framework_resources(project, resourcesPath):
|
||||
realPath = os.path.realpath(resourcesPath)
|
||||
files = project.get_files_by_os_path(realPath, tree="<absolute>")
|
||||
|
||||
if not files:
|
||||
files = project.add_file(realPath, parent=None, tree="<absolute>", create_build_files=False)
|
||||
|
||||
if files:
|
||||
framework = os.path.basename(os.path.dirname(resourcesPath))
|
||||
files[0]['name'] = framework + " Resources"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
action = sys.argv[1]
|
||||
|
||||
if action in ("add", "remove"):
|
||||
projectBasePath = unicode(sys.argv[2])
|
||||
projectSourcePath = unicode(sys.argv[3])
|
||||
sourcePath = os.path.realpath(projectSourcePath)
|
||||
|
||||
shadowBasePath = os.path.join(projectBasePath, ".XcodeSupport")
|
||||
shadowBasename = os.path.splitext(sourcePath)[0].replace(u"/", SLASH_REPLACEMENT)
|
||||
shadowHeaderPath = os.path.join(shadowBasePath, shadowBasename + ".h")
|
||||
shadowImplementationPath = os.path.join(shadowBasePath, shadowBasename + ".m")
|
||||
projectName = os.path.basename(projectBasePath)
|
||||
pbxPath = os.path.join(projectBasePath, projectName + ".xcodeproj", "project.pbxproj")
|
||||
|
||||
project = XcodeProject.Load(pbxPath)
|
||||
|
||||
shadowGroup = project.get_or_create_group("Classes")
|
||||
sourceGroup = project.get_or_create_group("Sources")
|
||||
|
||||
files = project.get_files_by_os_path(os.path.join(XCODESUPPORTFOLDER, os.path.basename(shadowHeaderPath)))
|
||||
|
||||
if action == "add":
|
||||
if len(files) == 0:
|
||||
update_general_include(project, projectBasePath)
|
||||
add_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationPath, sourcePath, projectBasePath)
|
||||
|
||||
match = FRAMEWORKS_RE.match(projectSourcePath)
|
||||
|
||||
if match:
|
||||
framework = match.group(2)
|
||||
resourcesPath = os.path.join(match.group(1), "Resources")
|
||||
|
||||
if os.path.isdir(resourcesPath):
|
||||
add_framework_resources(project, resourcesPath)
|
||||
|
||||
project.save()
|
||||
convert_unicode_to_xml(pbxPath)
|
||||
|
||||
elif action == "remove" and len(files) == 1:
|
||||
update_general_include(project, projectBasePath)
|
||||
remove_file(project, shadowGroup, sourceGroup, shadowHeaderPath, shadowImplementationPath, sourcePath, projectBasePath)
|
||||
project.save()
|
||||
Reference in New Issue
Block a user