Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implemented basic infrastructure for comment derived values handling.

  • Loading branch information...
commit e12fb72d4c90060178b8cd1269d3f0e2055b7b41 1 parent 1ad2f9d
@tomaz authored
View
42 Model/GBComment.h
@@ -9,29 +9,27 @@
#import <Foundation/Foundation.h>
@class GBSourceInfo;
-@class GBCommentParagraph;
-@class GBCommentArgument;
-@class GBParagraphLinkItem;
+@class GBCommentComponent;
+@class GBCommentComponentsList;
/** Handles all comment related stuff.
- Each instance describes a single source code comment for any object - class, category, protocol, method... As the comment is universal for each object, it contains properties for all fields applying to any kind of object. However not all are used in all cases. If a property is not used, it's value remains `nil`. Derived values are:
+ Each instance describes a single source code comment for any object - class, category, protocol, method... As the comment is universal for each object, it contains properties for all fields applying to any kind of object. However not all are used in all cases. If a property is not used, it's value remains `nil`. Derived values are handled with:
- - `paragraphs`: An array of `GBCommentParagraph` objects. The first entry is considered a short description, also available through `firstParagraph`.
- - `parameters`: An array of `GBCommentArgument` objects. Only applicable for methods with parameters.
- - `result`: A single `GBCommentArgument` object. Only applicable for methods with return value.
- - `exceptions`: An array of `GBCommentArgument` objects. Only applicable for methods with exceptions.
- - `crossrefs`: An array of `GBParagraphLinkItem` objects.
+ - `shortDescription`: Provides short description of the commented entity used for tooltips and abstract.
+ - `longDescription`: Provides the whole description of the commented entity. This can include `shortDescription` or not, based on settings.
+ - `methodParameters`: The list of all method parameters. Only used for methods.
+ - `methodResult`: Description of method result. Only used for methods.
+ - `methodExceptions`: The list of all possible exceptions. Only used for methods.
+ - `relatedItems`: The list of all related items. Used for cross referencing other entities.
- All arrays must be provided in the desired order of output - i.e. output formatters don't apply any sorting, they simply emit the values in the given order.
+ All lists must be provided in the desired order of output - i.e. output formatters don't apply any sorting, they simply emit the values in the given order.
`GBComment` is not context aware by itself, it's simply a container object that holds comment information. It's the rest of the application that's responsible for setting it's values as needed. In most cases it's `GBParser`s who sets comments string value and `GBProcessor`s to parse string value and setup the derived properties based on the comment's context.
@warning *Note:* Although derived values are prepared based on `stringValue`, nothing prevents clients to setup derived values directly, "on the fly" if needed. However splitting the interface allows us to simplify parsing code and allow us to handle derives values when we have complete information available.
*/
-@interface GBComment : NSObject {
- @private
-}
+@interface GBComment : NSObject
///---------------------------------------------------------------------------------------
/// @name Initialization & disposal
@@ -59,6 +57,24 @@
+ (id)commentWithStringValue:(NSString *)value sourceInfo:(GBSourceInfo *)info;
///---------------------------------------------------------------------------------------
+/// @name Comment components handling
+///---------------------------------------------------------------------------------------
+
+/** Comments short description used for tooltips and abstract in the form of `GBCommentComponent`.
+
+ @see longDescription
+ */
+@property (retain) GBCommentComponent *shortDescription;
+
+/** Comments long description, includes the whole description components.
+
+ Depending settings, this may also repeat `shortDescription` or not. `GBComment` assigns default object here, but clients are free to replace it with their own implementations.
+
+ @see shortDescription
+ */
+@property (retain) GBCommentComponentsList *longDescription;
+
+///---------------------------------------------------------------------------------------
/// @name Output generator helpers
///---------------------------------------------------------------------------------------
View
14 Model/GBComment.m
@@ -6,6 +6,7 @@
// Copyright (C) 2010, Gentle Bytes. All rights reserved.
//
+#import "GBDataObjects.h"
#import "GBComment.h"
@implementation GBComment
@@ -23,6 +24,14 @@ + (id)commentWithStringValue:(NSString *)value sourceInfo:(GBSourceInfo *)info {
return result;
}
+- (id)init {
+ self = [super init];
+ if (self) {
+ self.longDescription = [GBCommentComponentsList componentsList];
+ }
+ return self;
+}
+
#pragma mark Overriden methods
- (NSString *)description {
@@ -35,8 +44,11 @@ - (NSString *)debugDescription {
#pragma mark Properties
-@synthesize sourceInfo;
@synthesize isCopied;
+@synthesize sourceInfo;
@synthesize stringValue;
+@synthesize shortDescription;
+@synthesize longDescription;
+
@end
View
69 Model/GBCommentComponent.h
@@ -0,0 +1,69 @@
+//
+// GBCommentComponent.h
+// appledoc
+//
+// Created by Tomaz Kragelj on 14.2.11.
+// Copyright 2011 Gentle Bytes. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@class GBSourceInfo;
+
+/** Handles individual `GBComment` component.
+
+ A comment component is basic building block for `GBComment`s. It's primary responsibility is storing representation suitable for Markdown processor. The reason for splitting comment text into components is to allow support for various output styles, such as `@warning` and `@bug`. These require slightly different preprocessing. This object is lightweight, it doesn't do any processing, just provides properties that hold the data, it's the job of higher level components to setup the data properly.
+ */
+@interface GBCommentComponent : NSObject {
+ @private
+ NSString *_htmlValue;
+}
+
+///---------------------------------------------------------------------------------------
+/// @name Initialization & disposal
+///---------------------------------------------------------------------------------------
+
+/** Returns a new autoreleased instance of the comment with the given string value.
+
+ This is a helper initializer which allows setting string value with a single message. Sending this message is equivalent to sending `commentWithStringValue:sourceInfo:`, passing the given _value_ and `nil` for source info.
+
+ @param value String value to set.
+ @return Returns initialized object or `nil` if initialization fails.
+ @see commentWithStringValue:sourceInfo:
+ */
++ (id)componentWithStringValue:(NSString *)value;
+
+/** Returns a new autoreleased instance of the comment with the given string value and source info.
+
+ This is a helper initializer which allows setting default values with a single message.
+
+ @param value String value to set.
+ @param info Source info to set.
+ @return Returns initialized object or `nil` if initialization fails.
+ @see commentWithStringValue:
+ */
++ (id)componentWithStringValue:(NSString *)value sourceInfo:(GBSourceInfo *)info;
+
+///---------------------------------------------------------------------------------------
+/// @name Component data
+///---------------------------------------------------------------------------------------
+
+/** Component's string value from the source code.
+ */
+@property (copy) NSString *stringValue;
+
+/** Component's markdown value, derived from `stringValue`.
+ */
+@property (copy) NSString *markdownValue;
+
+/** Component's HTML value, derived by passing assigned `markdownValue` through Markdown processor.
+
+ This value is derived when first used, the value is cached afterwards and cached value is returned from subsequent calls.
+ */
+@property (readonly) NSString *htmlValue;
+
+/** Source file information.
+ */
+@property (retain) GBSourceInfo *sourceInfo;
+
+@end
View
40 Model/GBCommentComponent.m
@@ -0,0 +1,40 @@
+//
+// GBCommentComponent.m
+// appledoc
+//
+// Created by Tomaz Kragelj on 14.2.11.
+// Copyright 2011 Gentle Bytes. All rights reserved.
+//
+
+#import "GBCommentComponent.h"
+
+@implementation GBCommentComponent
+
+#pragma mark Initialization & disposal
+
++ (id)componentWithStringValue:(NSString *)value {
+ return [self componentWithStringValue:value sourceInfo:nil];
+}
+
++ (id)componentWithStringValue:(NSString *)value sourceInfo:(GBSourceInfo *)info {
+ GBCommentComponent *result = [[[self alloc] init] autorelease];
+ result.stringValue = value;
+ result.sourceInfo = info;
+ return result;
+}
+
+#pragma mark HTML processing
+
+- (NSString *)htmlValue {
+ if (_htmlValue) return _htmlValue;
+ _htmlValue = self.markdownValue;
+ return _htmlValue;
+}
+
+#pragma mark Properties
+
+@synthesize stringValue;
+@synthesize markdownValue;
+@synthesize sourceInfo;
+
+@end
View
47 Model/GBCommentComponentsList.h
@@ -0,0 +1,47 @@
+//
+// GBCommentComponentsList.h
+// appledoc
+//
+// Created by Tomaz Kragelj on 14.2.11.
+// Copyright 2011 Gentle Bytes. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+/** Handles a list of `GBCommentComponent`s.
+
+ Although we could handle the lists as `NSArray`s directly, having additional layer in-between unifies the access to the list.
+ */
+@interface GBCommentComponentsList : NSObject {
+ @private
+ NSMutableArray *_components;
+}
+
+///---------------------------------------------------------------------------------------
+/// @name Initialization & disposal
+///---------------------------------------------------------------------------------------
+
+/** Returns a new autoreleased instance of an empty list object.
+
+ This is just convenience initializer method.
+ */
++ (id)componentsList;
+
+///---------------------------------------------------------------------------------------
+/// @name List handling
+///---------------------------------------------------------------------------------------
+
+/** Registers the given `GBCommentComponent` to the `components` list.
+
+ The component is added to the end of the list.
+
+ @param component The component to register.
+ @exception NSException Thrown if the given component is `nil`.
+ */
+- (void)registerComponent:(id)component;
+
+/** The list of all components as `GBCommentComponent` instances in the list.
+ */
+@property (readonly) NSArray *components;
+
+@end
View
39 Model/GBCommentComponentsList.m
@@ -0,0 +1,39 @@
+//
+// GBCommentComponentsList.m
+// appledoc
+//
+// Created by Tomaz Kragelj on 14.2.11.
+// Copyright 2011 Gentle Bytes. All rights reserved.
+//
+
+#import "GBCommentComponentsList.h"
+
+@implementation GBCommentComponentsList
+
+#pragma mark Initialization & disposal
+
++ (id)componentsList {
+ return [[[self alloc] init] autorelease];
+}
+
+- (id)init {
+ self = [super init];
+ if (self) {
+ _components = [[NSMutableArray alloc] init];
+ }
+ return self;
+}
+
+#pragma mark Data handling
+
+- (void)registerComponent:(id)component {
+ NSParameterAssert(component != nil);
+ GBLogDebug(@"Registering component %@...", component);
+ [_components addObject:component];
+}
+
+#pragma mark Properties
+
+@synthesize components = _components;
+
+@end
View
2  Model/GBDataObjects.h
@@ -7,6 +7,8 @@
//
#import "GBComment.h"
+#import "GBCommentComponent.h"
+#import "GBCommentComponentsList.h"
#import "GBClassData.h"
#import "GBCategoryData.h"
View
52 Testing/GBCommentComponentsListTesting.m
@@ -0,0 +1,52 @@
+//
+// GBCommentComponentsListTesting.m
+// appledoc
+//
+// Created by Tomaz Kragelj on 14.2.10.
+// Copyright (C) 2011 Gentle Bytes. All rights reserved.
+//
+
+#import "GBDataObjects.h"
+
+@interface GBCommentComponentsListTesting : GHTestCase
+@end
+
+@implementation GBCommentComponentsListTesting
+
+#pragma mark Initialization & disposal
+
+- (void)testInit_shouldInitializeEmptyList {
+ // setup & execute
+ GBCommentComponentsList *list = [[GBCommentComponentsList alloc] init];
+ // verify
+ assertThat(list.components, isNot(nil));
+ assertThatInteger([list.components count], equalToInteger(0));
+}
+
+#pragma mark Registration testing
+
+- (void)testRegisterComponent_shouldAddComponentToComponentsArray {
+ // setup
+ GBCommentComponentsList *list = [[GBCommentComponentsList alloc] init];
+ // execute
+ [list registerComponent:[GBCommentComponent componentWithStringValue:@"a"]];
+ // verify
+ assertThatInteger([list.components count], equalToInteger(1));
+ assertThat([[list.components objectAtIndex:0] stringValue], is(@"a"));
+}
+
+- (void)testRegisterComponent_shouldAddComponentsToArrayInOrder {
+ // setup
+ GBCommentComponentsList *list = [[GBCommentComponentsList alloc] init];
+ // execute
+ [list registerComponent:[GBCommentComponent componentWithStringValue:@"a"]];
+ [list registerComponent:[GBCommentComponent componentWithStringValue:@"b"]];
+ [list registerComponent:[GBCommentComponent componentWithStringValue:@"c"]];
+ // verify
+ assertThatInteger([list.components count], equalToInteger(3));
+ assertThat([[list.components objectAtIndex:0] stringValue], is(@"a"));
+ assertThat([[list.components objectAtIndex:1] stringValue], is(@"b"));
+ assertThat([[list.components objectAtIndex:2] stringValue], is(@"c"));
+}
+
+@end
View
8 Testing/GBCommentTesting.m
@@ -13,5 +13,13 @@ @interface GBCommentTesting : GHTestCase
@implementation GBCommentTesting
+#pragma mark Initialization & disposal
+
+- (void)testInit_shouldSetupDefaultComponents {
+ // setup & execute
+ GBComment *comment = [GBComment commentWithStringValue:@""];
+ // verify
+ assertThat(comment.longDescription, isNot(nil));
+}
@end
View
20 appledoc.xcodeproj/project.pbxproj
@@ -154,6 +154,11 @@
739C0C4712AC258B00F0130B /* GBProcessor-UndocumentedObjectsTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = 739C0C4612AC258B00F0130B /* GBProcessor-UndocumentedObjectsTesting.m */; };
739C0C4912AC284E00F0130B /* GBProcessor-CategoriesMergingTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = 739C0C4812AC284E00F0130B /* GBProcessor-CategoriesMergingTesting.m */; };
73AA9F731253BF4000074152 /* GBGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AA9F721253BF4000074152 /* GBGenerator.m */; };
+ 73AF4EC813093570001152DB /* GBCommentComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AF4EC713093570001152DB /* GBCommentComponent.m */; };
+ 73AF4EC913093570001152DB /* GBCommentComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AF4EC713093570001152DB /* GBCommentComponent.m */; };
+ 73AF4ECC130938F3001152DB /* GBCommentComponentsList.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AF4ECB130938F3001152DB /* GBCommentComponentsList.m */; };
+ 73AF4ECD130938F3001152DB /* GBCommentComponentsList.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AF4ECB130938F3001152DB /* GBCommentComponentsList.m */; };
+ 73AF4ECF13093B5A001152DB /* GBCommentComponentsListTesting.m in Sources */ = {isa = PBXBuildFile; fileRef = 73AF4ECE13093B5A001152DB /* GBCommentComponentsListTesting.m */; };
73CF8131122D3824005B7E26 /* RegexKitLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 73CF8130122D3824005B7E26 /* RegexKitLite.m */; };
73CF8132122D3824005B7E26 /* RegexKitLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 73CF8130122D3824005B7E26 /* RegexKitLite.m */; };
73D2524612A2ED610024F9F9 /* GBOutputGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 73D2524512A2ED610024F9F9 /* GBOutputGenerator.m */; };
@@ -326,6 +331,11 @@
73A32FB112364BC100040070 /* GBObjectDataProviding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GBObjectDataProviding.h; sourceTree = "<group>"; };
73AA9F711253BF4000074152 /* GBGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GBGenerator.h; sourceTree = "<group>"; };
73AA9F721253BF4000074152 /* GBGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GBGenerator.m; sourceTree = "<group>"; };
+ 73AF4EC61309356F001152DB /* GBCommentComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GBCommentComponent.h; sourceTree = "<group>"; };
+ 73AF4EC713093570001152DB /* GBCommentComponent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GBCommentComponent.m; sourceTree = "<group>"; };
+ 73AF4ECA130938F3001152DB /* GBCommentComponentsList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GBCommentComponentsList.h; sourceTree = "<group>"; };
+ 73AF4ECB130938F3001152DB /* GBCommentComponentsList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GBCommentComponentsList.m; sourceTree = "<group>"; };
+ 73AF4ECE13093B5A001152DB /* GBCommentComponentsListTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GBCommentComponentsListTesting.m; sourceTree = "<group>"; };
73CF8130122D3824005B7E26 /* RegexKitLite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegexKitLite.m; sourceTree = "<group>"; };
73D2524312A2EA340024F9F9 /* html */ = {isa = PBXFileReference; lastKnownFileType = folder; path = html; sourceTree = "<group>"; };
73D2524412A2ED610024F9F9 /* GBOutputGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GBOutputGenerator.h; sourceTree = "<group>"; };
@@ -816,6 +826,10 @@
children = (
73F70DB51227B34300D19EBA /* GBComment.h */,
73F70DB61227B34300D19EBA /* GBComment.m */,
+ 73AF4EC61309356F001152DB /* GBCommentComponent.h */,
+ 73AF4EC713093570001152DB /* GBCommentComponent.m */,
+ 73AF4ECA130938F3001152DB /* GBCommentComponentsList.h */,
+ 73AF4ECB130938F3001152DB /* GBCommentComponentsList.m */,
);
name = Comments;
sourceTree = "<group>";
@@ -861,6 +875,7 @@
73FC730F11FDAB8E00AAD0B9 /* GBIvarsProviderTesting.m */,
73FC741911FE210100AAD0B9 /* GBMethodsProviderTesting.m */,
733E9FB8122B9D510060CBDE /* GBCommentTesting.m */,
+ 73AF4ECE13093B5A001152DB /* GBCommentComponentsListTesting.m */,
);
name = Model;
sourceTree = "<group>";
@@ -1189,6 +1204,9 @@
7317CC0C12B10E3F009DAA15 /* GBApplicationTesting.m in Sources */,
73368F1112F42AE000A54A74 /* GBCommentComponentsProviderTesting.m in Sources */,
735B238413040CEB00704844 /* GBDocumentDataTesting.m in Sources */,
+ 73AF4EC913093570001152DB /* GBCommentComponent.m in Sources */,
+ 73AF4ECD130938F3001152DB /* GBCommentComponentsList.m in Sources */,
+ 73AF4ECF13093B5A001152DB /* GBCommentComponentsListTesting.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1267,6 +1285,8 @@
7335F72E12E58E160094F72E /* GBDocSetPublishGenerator.m in Sources */,
735B23811304024600704844 /* GBDocumentData.m in Sources */,
735B2387130418A100704844 /* GBTemplateFilesHandler.m in Sources */,
+ 73AF4EC813093570001152DB /* GBCommentComponent.m in Sources */,
+ 73AF4ECC130938F3001152DB /* GBCommentComponentsList.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Please sign in to comment.
Something went wrong with that request. Please try again.