Fix a bug that caused an assert failed when accessing an empty string in `Text::is_int`
Reported by @xymus with PR #1649
Pull-Request: #1650
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Jean Privat <jean@pryen.org>
--custom-brand "<a href=\"http://nitlanguage.org/\">Nitlanguage.org</a>" \
--custom-overview-text "<p>Documentation for the standard library of Nit<br/>Version $$(git describe)<br/>Date: $$(git show --format="%cd" | head -1)</p>" \
--custom-footer-text "Nit standard library. Version $$(git describe)." \
- --github-upstream "privat:nit:master" \
+ --github-upstream "nitlang:nit:master" \
--github-base-sha1 "$$(git rev-parse HEAD)" \
--github-gitdir "." \
- --source "https://github.com/privat/nit/blob/$$(git rev-parse HEAD)/%f#L%l-%L" \
+ --source "https://github.com/nitlang/nit/blob/$$(git rev-parse HEAD)/%f#L%l-%L" \
--piwik-tracker "pratchett.info.uqam.ca/piwik/" \
--piwik-site-id "2" \
--custom-brand "<a href=\"http://nitlanguage.org/\">Nitlanguage.org</a>" \
--custom-overview-text "<p>Documentation for the Nit tools<br/>Version $$(git describe)<br/>Date: $$(git show --format="%cd" | head -1)</p>" \
--custom-footer-text "Nit tools. Version $$(git describe)." \
- --github-upstream "privat:nit:master" \
+ --github-upstream "nitlang:nit:master" \
--github-base-sha1 "$$(git rev-parse HEAD)" \
--github-gitdir "." \
- --source "https://github.com/privat/nit/blob/$$(git rev-parse HEAD)/%f#L%l-%L" \
+ --source "https://github.com/nitlang/nit/blob/$$(git rev-parse HEAD)/%f#L%l-%L" \
--piwik-tracker "pratchett.info.uqam.ca/piwik/" \
--piwik-site-id "3"
License:Apache2
Web Site:http://nitlanguage.org
Source Code:http://nitlanguage.org/nit.git/tree/HEAD:/examples/mnit_moles
-Issue Tracker:https://github.com/privat/nit/issues
+Issue Tracker:https://github.com/nitlang/nit/issues
Summary:Wack-a-Mole game
Description:
License:WTFPL
Web Site:http://nitlanguage.org
Source Code:http://nitlanguage.org/nit.git/tree/HEAD:/contrib/friendz
-Issue Tracker:https://github.com/privat/nit/issues
+Issue Tracker:https://github.com/nitlang/nit/issues
Summary:Puzzle game
Description:
# Get a given pull request (PR)
fun getpr(number: Int): JsonObject
do
- var pr = get_and_check("https://api.github.com/repos/privat/nit/pulls/{number}")
+ var pr = get_and_check("https://api.github.com/repos/nitlang/nit/pulls/{number}")
var prm = pr.json_as_map
var sha = prm["head"].json_as_map["sha"].to_s
- var statuses = get_and_check("https://api.github.com/repos/privat/nit/statuses/{sha}")
+ var statuses = get_and_check("https://api.github.com/repos/nitlang/nit/statuses/{sha}")
prm["statuses"] = statuses
print "{prm["title"].to_s}: by {prm["user"].json_as_map["login"].to_s} (# {prm["number"].to_s})"
var mergeable = prm["mergeable"]
var number = pr["number"].as(Int)
var user = pr["user"].json_as_map["login"].as(String)
var comments = new Array[nullable Object]
- comments.add_all(get_and_check("https://api.github.com/repos/privat/nit/issues/{number}/comments").json_as_a)
- comments.add_all(get_and_check("https://api.github.com/repos/privat/nit/pulls/{number}/comments").json_as_a)
+ comments.add_all(get_and_check("https://api.github.com/repos/nitlang/nit/issues/{number}/comments").json_as_a)
+ comments.add_all(get_and_check("https://api.github.com/repos/nitlang/nit/pulls/{number}/comments").json_as_a)
var logins = new Array[String]
for c in comments do
var cm = c.json_as_map
print " git config --add github.oauthtoken MYOAUTHTOKEN"
end
-var curl = new GithubCurl(auth, "Merge-o-matic (privat/nit)")
+var curl = new GithubCurl(auth, "Merge-o-matic (nitlang/nit)")
if args.length != 1 then
# Without args, list `ok_will_merge`
- var x = curl.get_and_check("https://api.github.com/repos/privat/nit/issues?labels=ok_will_merge")
+ var x = curl.get_and_check("https://api.github.com/repos/nitlang/nit/issues?labels=ok_will_merge")
for y in x.json_as_a do
var number = y.json_as_map["number"].as(Int)
curl.getpr(number)
* Shop: exchange Nitcoins against glorifying items
You can suggest new achievements or ideas in the
-[NitRPG RoadMap Issue](https://github.com/privat/nit/issues/1161).
+[NitRPG RoadMap Issue](https://github.com/nitlang/nit/issues/1161).
// @name Github.com - Add RPG tab
// @namespace nitlanguage/github/rpg
// @description Adds a "Github RPG" Tab at the end of the tabs.
-// @include https://github.com/privat/nit*
+// @include https://github.com/nitlang/nit*
// @version 1
// @grant none
// ==/UserScript==
/* TODO:
* Link to the player page (if logged and is a player)
- * Link to other games (not just `privat/nit` but other)
+ * Link to other games (not just `nitlang/nit` but other)
*/
// The nav bar with tabs
// The new tab
var html = '<li class="tooltipped tooltipped-w" aria-label="Github RPG">\
- <a href="http://nitlanguage.org/rpg/games/privat/nit" aria-label="RPG" class="js-selected-navigation-item sunken-menu-item" data-selected-links="repo_settings /privat/nit/settings">\
+ <a href="http://nitlanguage.org/rpg/games/nitlang/nit" aria-label="RPG" class="js-selected-navigation-item sunken-menu-item" data-selected-links="repo_settings /nitlang/nit/settings">\
<span class="octicon octicon-ruby"></span> <span class="full-word">Github RPG</span>\
<img alt="" class="mini-loader" height="16" src="https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif" width="16">\
</a></li>';
# Returns the repo `full_name`.
#
- # Example: `"privat/nit"`
+ # Example: `"nitlang/nit"`
redef fun key do return repo.full_name
# We need a `GithubAPI` client to load Github data.
--- /dev/null
+src/objc_lexer.nit
+src/objc_parser.nit
+src/objc_test_parser.nit
+tests/MyClass.nit
+objc.ast.dot
--- /dev/null
+all: bin/objcwrapper
+
+../nitcc/src/nitcc:
+ make -C ../nitcc
+
+src/objc_parser.nit: ../nitcc/src/nitcc grammar/objc.sablecc
+ ../nitcc/src/nitcc grammar/objc.sablecc
+ mv *.nit src/
+ mv objc* gen/
+
+bin/objcwrapper: $(shell ../../bin/nitls -M src/objcwrapper.nit) src/objc_parser.nit
+ ../../bin/nitc -o bin/objcwrapper src/objcwrapper.nit --semi-global
+
+bin/objc_test_parser: $(shell ../../bin/nitls -M src/objc_test_parser.nit)
+ ../../bin/nitc -o bin/objc_test_parser src/objc_test_parser.nit --semi-global
+
+check: bin/objc_test_parser bin/objcwrapper
+ # Test the parser
+ bin/objc_test_parser tests/MyClass.h
+
+ # Test objcwrapper
+ bin/objcwrapper tests/MyClass.h -o tests/MyClass.nit
+ ../../bin/nitpick tests/MyClass.nit
+
+# Test on classes of libgnustep-base-dev
+check-gnustep:
+ gcc -E /usr/include/GNUstep/Foundation/NSArray.h -I /usr/include/GNUstep/ -Wno-deprecated \
+ | ../header_keeper/bin/header_keeper /usr/include/GNUstep/Foundation/NSArray.h \
+ | bin/header_static > tests/NSArray.pre.h
+ bin/objcwrapper tests/NSArray.pre.h
+ ../../bin/nitpick NSArray.nit
+
+# Test on classes of the Apple Foundation framework
+check-apple:
+ gcc -E /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSArray.h \
+ | ../header_keeper/bin/header_keeper /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSArray.h \
+ | bin/header_static > tests/NSArray.pre.h
+ bin/objcwrapper tests/NSArray.pre.h
+ ../../bin/nitpick NSArray.nit
+
+bin/header_static:
+ ../../bin/nitc --dir bin src/header_static.nit
--- /dev/null
+/* Grammar for Objective-C header files */
+Grammar objc;
+
+Lexer
+ upper = 'A'..'Z';
+ lower = 'a'..'z';
+ letter = upper | lower;
+ digit = '0'..'9';
+
+ comma = ',';
+ lpar = '(';
+ rpar = ')';
+ star = '*';
+
+ string = '"' (Any - '"')* '"';
+ class = upper (letter | '_' | digit)*;
+ id = lower (letter | '_' | digit)*;
+
+ private = '_' (letter | digit)+;
+ num = digit+;
+ macro_name = '__' (letter | '_')+;
+ num_typed = num upper+;
+ hexadecimal = '0x' (letter | digit)+;
+ pointer = star+;
+
+ blank = (' ' | '\t' | '\n')+;
+ comments = ('#' (Any - '\n')*);
+
+Parser
+ Ignored blank, comments;
+
+ prog = lines*;
+
+ lines =
+ {class:} '@class' classes ';' |
+ {protocol:} protocol |
+ {attribute:} attribute |
+ {static:} static |
+ {structure:} structure |
+ {interface:} '@interface' class interface? inheritance? protocols? instance_variables? interface_block* '@end' |
+ {line:} line;
+
+ interface_block =
+ {line:} line |
+ {instance:} instance_declaration;
+
+ line =
+ {library_extern_declaration:} library_extern_declaration |
+ {typedef:} typedef |
+ {extern:} extern |
+ {enum:} 'enum' '{' params '}' attribute? ';';
+
+ typedef =
+ {variable:} 'typedef' 'struct'? declaration ';' |
+ {method:} 'typedef' type method ';' |
+ {structure:} 'typedef' structure |
+ {anonymous:} 'typedef' type anonymous ';';
+
+ instance_declaration =
+ {signature:} signature_block |
+ {property:} property_declaration;
+
+ property_declaration =
+ {property:} optional_method? '@property' property_attribute? property attribute* ';';
+
+ property_attribute =
+ {attribute:} lpar params rpar;
+
+ interface =
+ {interface:} lpar params? rpar;
+
+ library_extern_declaration =
+ {simple:} 'UIKIT_EXTERN' type pointer? 'const'? term attribute? ';' |
+ {method:} 'UIKIT_EXTERN' type method? attribute? ';';
+
+ protocol =
+ {declaration:} '@protocol' type additional_type* ';' |
+ {construction:} '@protocol' type protocols? protocol_block+ '@end';
+
+ additional_type =
+ {type:} comma type;
+
+ protocol_block =
+ {signature:} signature_block |
+ {property:} property_declaration;
+
+ signature_block =
+ {signature:} optional_method? scope signature_return_type? parameter+ attribute_list? ';';
+
+ signature_return_type =
+ {return:} lpar type pointer? function_pointer? protocols? rpar;
+
+ optional_method =
+ {required:} '@required' |
+ {optional:} '@optional';
+
+ method =
+ {call:} pointer? term lpar args rpar |
+ {declaration:} pointer? term lpar declarations rpar;
+
+ attribute_list =
+ {attr:} attribute+;
+
+ attribute =
+ {availability:} '__attribute__' lpar lpar 'availability' lpar params rpar rpar rpar |
+ {visibility:} '__attribute__' lpar lpar 'visibility' lpar term rpar rpar rpar |
+ {objc_gc:} '__attribute__' lpar lpar 'objc_gc' lpar term rpar rpar rpar |
+ {attribute_id:} '__attribute__' lpar lpar term rpar rpar |
+ {attribute_method:} '__attribute__' lpar lpar method rpar rpar;
+
+ extern =
+ {method:} 'extern' type method attribute? ';' |
+ {simple:} 'extern' type pointer? 'const'? term attribute? ';';
+
+ static =
+ {method:} 'static' 'inline' type method attribute? ';' |
+ {attr:} 'static' '__inline__' attribute+ type method attribute? ';';
+
+ scope =
+ {class:} '+' |
+ {instance:} '-';
+
+ parameter =
+ {named:} [left:]term ':' lpar parameter_type rpar attribute? [right:]term |
+ {single:} term |
+ {comma:} comma '...' |
+ {macro:} macro_name;
+
+ parameter_type =
+ {normal:} type |
+ {anonymous:} type anonymous |
+ {table:} type protocols? '[]' |
+ {pointer:} type pointer |
+ {protocol:} type protocols |
+ {unsigned:} unsigned pointer |
+ {function_pointer:} function_pointer;
+
+ anonymous =
+ {method:} lpar '^' term? rpar lpar declarations? rpar |
+ {inception:} lpar '^' term? rpar lpar type lpar '^' term? rpar lpar type rpar rpar;
+
+ property =
+ {property:} type protocols? pointer? [left:]term [right:]term? |
+ {anonymous:} type anonymous |
+ {function_pointer:} function_pointer;
+
+ type =
+ {type:} type_annotation? unsigned? data_type;
+
+ type_annotation =
+ {const:} 'const' |
+ {in:} 'in' |
+ {out:} 'out' |
+ {inout:} 'inout' |
+ {bycopy:} 'bycopy' |
+ {byref:} 'byref';
+
+ unsigned =
+ {u:} 'unsigned' |
+ {s:} 'signed';
+
+ data_type =
+ {more:} more_type |
+ {otype:} class;
+
+ more_type =
+ 'uuid_t' |
+ 'id' |
+ '_Bool' |
+ 'pthread_mutex_t' |
+ 'dispatch_semaphore_t' |
+ 'dispatch_queue_t' |
+ 'va_list' |
+ 'SecIdentityRef' |
+ 'SecTrustRef' |
+ 'Class' |
+ 'Protocol' |
+ 'void' |
+ 'uint8_t' |
+ 'uint16_t' |
+ 'uint32_t' |
+ 'uint64_t' |
+ 'int8_t' |
+ 'int16_t' |
+ 'int32_t' |
+ 'int64_t' |
+ 'unichar' |
+ 'char' |
+ 'short' |
+ 'short int' |
+ 'int' |
+ 'long' |
+ 'long int' |
+ 'long long' |
+ 'long long int' |
+ 'float' |
+ 'double' |
+ 'long double';
+
+ classe =
+ {class:} class |
+ {protocol:} 'Protocol';
+
+ classes =
+ {classes:} classe additional*;
+
+ protocols =
+ {protocols:} '<' classe additional* '>';
+
+ inheritance =
+ {add:} ':' classe additional*;
+
+ additional =
+ {add:} comma classe;
+
+ declarations =
+ {declarations:} declaration additional_declaration*;
+
+ additional_declaration =
+ {add:} comma declaration;
+
+ declaration =
+ {pointer:} type protocols? attribute? pointer? term? '[]'? |
+ {typedef:} type more_type |
+ {function_pointer:} function_pointer |
+ {comma:} '...';
+
+ declaration_variable_instance =
+ {unsigned:} type_annotation? unsigned more_type? protocols? attribute? pointer? term '[]'? |
+ {data_type:} type_annotation? data_type protocols? attribute? pointer? term? '[]'?;
+
+ instance_variables =
+ {instance:} '{' instance_variable* '}';
+
+ scope_instance_variable =
+ {package:} '@package' |
+ {public:} '@public' |
+ {private:} '@private' |
+ {protected:} '@protected';
+
+ instance_variable =
+ {scope:} scope_instance_variable |
+ {variable:} attribute? declaration_variable_instance bit_field? additional_variable* ';' |
+ {anonymous:} declaration_variable_instance anonymous ';' |
+ {structure:} structure |
+ {union:} union;
+
+ additional_variable =
+ {add} comma term bit_field?;
+
+ function_pointer =
+ {type:} type pointer? lpar pointer term? rpar lpar declarations rpar;
+
+ union =
+ {name:} 'union' '{' structure_params+ '}' term ';';
+
+ structure =
+ {name:} 'struct' structure_core term ';' |
+ {type:} 'struct' type structure_core term? ';' |
+ {private:} 'struct' private structure_core? term? ';';
+
+ structure_core =
+ {core:} '{' structure_params+ '}';
+
+ structure_params =
+ {value:} declaration bit_field? ';' |
+ {structure:} structure;
+
+ params =
+ {params:} param additional_params*;
+
+ additional_params =
+ {add:} comma param?;
+
+ param =
+ {id:} term |
+ {bitwise:} term '=' bitwise |
+ {term:} term '=' pointer? term+ |
+ {attr:} term attribute |
+ {attrterm:} term attribute '=' term |
+ {attrbitwise:} term attribute '=' bitwise;
+
+ args =
+ {args:} arg additional_arg*;
+
+ additional_arg =
+ {add:} comma arg;
+
+ arg =
+ {num:} num |
+ {macro:} macro_name;
+
+ bitwise =
+ {rterm:} bitwise_operator_not? term bitwise_operator bitwise_operator_not? term |
+ {num:} lpar bitwise_operator_not? term rpar |
+ {term:} lpar bitwise_operator_not? term additional_bitwise+ rpar arithmetic?;
+
+ bitwise_operator =
+ {left_shift:} '<<' |
+ {right_shift:} '>>' |
+ {and:} '&' |
+ {or:} '|' |
+ {xor:} '^';
+
+ bitwise_operator_not =
+ {not:} '~';
+
+ additional_bitwise =
+ {add:} bitwise_operator bitwise_operator_not? term;
+
+ bit_field =
+ {value:} ':' num;
+
+ arithmetic =
+ {add:} '+' num |
+ {minus:} '-' num |
+ {star:} pointer num |
+ {divide:} '/' num;
+
+ term =
+ {num_typed:} '-'? num_typed |
+ {private:} private |
+ {num:} num |
+ {negative:} '-' num |
+ {float:} num '.' num |
+ {string:} string |
+ {hexadecimal:} hexadecimal |
+ {class:} class |
+ {var:} id |
+ {private_table:} private '[' lpar? num rpar? ']' |
+ {table:} id '[' lpar? num rpar? ']';
+++ /dev/null
-bin/header_static:
- mkdir -p bin
- ../../../bin/nitc --dir bin src/header_static.nit
-
-tests: bin/header_static
- cat CGGeometry.h | bin/header_static > static_CGGeometry.h
- cat NSObject.h | bin/header_static > static_NSObject.h
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Code generation
+module objc_generator
+
+import opts
+
+import objc_model
+
+redef class Sys
+ # Path to the output file
+ var opt_output = new OptionString("Output file", "-o")
+end
+
+class CodeGenerator
+ # Merge the calls to `alloc` and `init...` in a single constructor?
+ #
+ # If `true`, also the default behavior, initializing an extern Objective-C object looks like:
+ # ~~~nitish
+ # var o = new NSArray.init_with_array(some_other_array)
+ # ~~~
+ #
+ # If `false`, the object must first be allocated and then initialized.
+ # This is closer to the Objective-C behavior:
+ # ~~~nitish
+ # var o = new NSArray
+ # o.init_with_array(some_other_array)
+ # ~~~
+ var init_with_alloc = true is writable
+
+ # Generate Nit code to wrap `classes`
+ fun generate(classes: Array[ObjcClass])
+ do
+ # Open specified path or stdin
+ var file
+ var path = opt_output.value
+ if path != null then
+ if path.file_extension != "nit" then
+ print_error "Warning: output file path does not end with '.nit'"
+ end
+
+ file = new FileWriter.open(path)
+ else
+ file = stdout
+ end
+
+ # Generate code
+ file.write "import cocoa::foundation\n\n"
+ for classe in classes do
+ write_class(classe, file)
+ end
+
+ if path != null then file.close
+ end
+
+ private fun type_convertor(type_word: String): String
+ do
+ var types = new HashMap[String, String]
+ types["char"] = "Byte"
+ types["short"] = "Int"
+ types["short int"] = "Int"
+ types["int"] = "Int"
+ types["long"] = "Int"
+ types["long int"] = "Int"
+ types["long long"] = "Int"
+ types["long long int"] = "Int"
+ types["float"] = "Float"
+ types["double"] = "Float"
+ types["long double"] = "Float"
+
+ types["NSUInteger"] = "Int"
+ types["BOOL"] = "Bool"
+ types["id"] = "NSObject"
+
+ if types.has_key(type_word) then
+ return types[type_word]
+ else
+ return type_word
+ end
+ end
+
+ private fun write_class(classe: ObjcClass, file: Writer)
+ do
+ var commented_methods = new Array[ObjcMethod]
+ file.write "extern class " + classe.name + """ in "ObjC" `{ """ + classe.name + """ * `}\n"""
+ for super_name in classe.super_names do
+ file.write """ super """ + super_name + "\n"
+ end
+ if classe.super_names.is_empty then file.write """ super NSObject\n"""
+ write_constructor(classe, file)
+ file.write "\n"
+ for attribute in classe.attributes do
+ write_attribute(attribute, file)
+ end
+ for method in classe.methods do
+ if method.is_commented then
+ commented_methods.add(method)
+ else
+ if init_with_alloc and method.params.first.name.has("init") then continue
+ file.write """ """
+ write_method(method, file)
+ file.write """ in "ObjC" `{\n """
+ write_objc_method_call(method, file)
+ file.write """ `}"""
+ if method != classe.methods.last then file.write "\n\n"
+ end
+ end
+ for commented_method in commented_methods do
+ if commented_method == commented_methods.first then file.write "\n"
+ file.write """ #"""
+ write_method(commented_method, file)
+ if commented_method != commented_methods.last then file.write "\n"
+ end
+ file.write "\nend\n"
+ end
+
+ private fun write_constructor(classe: ObjcClass, file: Writer)
+ do
+ if init_with_alloc then
+ for method in classe.methods do
+ if method.params.first.name.has("init") and not method.is_commented then
+ file.write """\n """
+ if method.params.first.name == "init" then
+ file.write "new"
+ else
+ write_method(method, file)
+ end
+ file.write """ in "ObjC" `{\n"""
+ write_objc_init_call(classe.name, method, file)
+ file.write """ `}\n"""
+ end
+ end
+ else
+ file.write """\n new in "ObjC"`{\n"""
+ file.write """ return [""" + classe.name + " alloc];\n"
+ file.write """ `}\n"""
+ end
+ end
+
+ private fun write_attribute(attribute: ObjcAttribute, file: Writer)
+ do
+ write_attribute_getter(attribute, file)
+ # TODO write_attribute_setter if there is no `readonly` annotation
+ file.write "\n"
+ end
+
+ private fun write_attribute_getter(attribute: ObjcAttribute, file: Writer)
+ do
+ file.write """ fun """ + attribute.name.to_snake_case + ": " + type_convertor(attribute.return_type)
+ file.write """ in "ObjC" `{\n"""
+ file.write """ return [self """ + attribute.name + "];\n"
+ file.write """ `}\n"""
+ end
+
+ private fun write_attribute_setter(attribute: ObjcAttribute, file: Writer)
+ do
+ file.write """ fun """ + attribute.name.to_snake_case + "=(value: " + type_convertor(attribute.return_type) + ")"
+ file.write " in \"ObjC\" `\{\n"
+ file.write """ self.""" + attribute.name + " = value;\n"
+ file.write """ `}\n"""
+ end
+
+ private fun write_method(method: ObjcMethod, file: Writer)
+ do
+ var name = ""
+ for param in method.params do
+ name += param.name[0].to_upper.to_s + param.name.substring_from(1)
+ name = name.to_snake_case
+ end
+ if name.has("init") and init_with_alloc then
+ file.write "new "
+ else
+ if not init_with_alloc and name == "init" then name = "init_0"
+ file.write "fun "
+ end
+ file.write name
+ for param in method.params do
+ if param == method.params.first and not param.is_single then
+ file.write "(" + param.variable_name + ": " + type_convertor(param.return_type)
+ end
+ if param != method.params.first and not param.is_single then
+ file.write ", " + param.variable_name + ": " + type_convertor(param.return_type)
+ end
+ if param == method.params.last and not param.is_single then
+ file.write ")"
+ end
+ end
+ if method.return_type != "void" and not method.params.first.name.has("init") then
+ file.write ": " + type_convertor(method.return_type)
+ end
+ end
+
+ private fun write_objc_init_call(classe_name: String, method: ObjcMethod, file: Writer)
+ do
+ file.write """ return [[""" + classe_name + " alloc] "
+ for param in method.params do
+ if not param.is_single then
+ file.write param.name + ":" + param.variable_name
+ if not param == method.params.last then file.write " "
+ else
+ file.write param.name
+ end
+ end
+ file.write "];\n"
+ end
+
+ private fun write_objc_method_call(method: ObjcMethod, file: Writer)
+ do
+ if method.return_type != "void" then file.write "return "
+ file.write "[self "
+ for param in method.params do
+ if not param.is_single then
+ file.write param.name + ":" + param.variable_name
+ if not param == method.params.last then file.write " "
+ else
+ file.write param.name
+ end
+ end
+ file.write "];\n"
+ end
+end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Model of the parsed Objective-C files
+module objc_model
+
+# Model of all the analyzed Objective-C classes
+class ObjcModel
+ # All analyzed classes
+ var classes = new Array[ObjcClass]
+end
+
+# Objective-C class
+class ObjcClass
+ # Name of the super classes
+ var super_names = new Array[String]
+
+ # Name of this Objective-C class
+ var name: String
+
+ # Attributes of this Objective-C class
+ var attributes = new Array[ObjcAttribute]
+
+ # Methods of this Objective-C class
+ var methods = new Array[ObjcMethod]
+end
+
+# Method of an `ObjcClass`
+class ObjcMethod
+ super Property
+
+ # Scope: '+' for a static class method, and '-' for an instance method
+ var scope: Char is noinit, writable
+
+ # Parameters of the method
+ var params = new Array[Param]
+
+ # Return type as a `String`
+ var return_type: String is noinit, writable
+end
+
+# Attribute of an `ObjcClass`
+class ObjcAttribute
+ super Property
+
+ # Name of this attribute
+ var name: String is noinit, writable
+
+ # Type of this attribute
+ var return_type: String is noinit, writable
+end
+
+# Property of an `ObjcClass`
+class Property
+ # Is this property to be commented out?
+ var is_commented = false is writable
+end
+
+# Parameter of an `ObjcMethod`
+class Param
+ # Parameter name, used by the caller (e.g. `withObject` in `withObject: (NSObject*) obj`)
+ var name: String is noinit, writable
+
+ # Type of the parameter name
+ var return_type: String is noinit, writable
+
+ # Argument name, used within the body (e.g. `obj` in `withObject: (NSObject*) obj`)
+ var variable_name: String is noinit, writable
+
+ # Is this a primitive array? with at least one `[]`.
+ var is_table = false is writable
+
+ # Is this a pointer type?
+ var is_pointer = false is writable
+
+ # Is this a parameter with only a `name`?
+ var is_single = false is writable
+end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# AST visitor
+module objc_visitor
+
+import objc_model
+import objc_parser
+
+# AST visitor building `model` from the parsed class headers
+class ObjcVisitor
+ super Visitor
+
+ # `ObjcModel` in construction
+ var model = new ObjcModel
+
+ # `ObjcClass` in construction, if any
+ private var objc_class: nullable ObjcClass = null
+
+ redef fun visit(n) do n.accept_objc(self)
+end
+
+redef class Node
+ private fun accept_objc(v: ObjcVisitor) do visit_children(v)
+end
+
+# ---
+# Main nodes
+
+# Class declaration
+redef class Nlines_interface
+ redef fun accept_objc(v)
+ do
+ var interface_block = n_interface_block
+ if interface_block == null then return
+
+ # If reopening a class, continue with the exisitng one
+ var c = null
+ for objc_class in v.model.classes do
+ if objc_class.name == n_class.text then
+ c = objc_class
+ end
+ end
+
+ # New class
+ if c == null then
+ c = new ObjcClass(n_class.text)
+ v.model.classes.add c
+ end
+ v.objc_class = c
+
+ # Visit superclass declarations
+ var inheritance_block = n_inheritance
+ if inheritance_block != null then v.enter_visit(inheritance_block)
+
+ # Visit main body
+ v.enter_visit(interface_block)
+ end
+end
+
+# Method or function declaration
+redef class Nsignature_block_signature
+ redef fun accept_objc(v)
+ do
+ var method = new ObjcMethod
+ method.return_type = n_signature_return_type.to_type
+ method.scope = if n_scope.is_class_property then '-' else '+'
+
+ for n_param in n_parameter.children do
+ var param = n_param.to_param
+ if param == null then
+
+ # Unsupported parameter format
+ method.is_commented = true
+
+ # Use a placeholder for easier debugging
+ param = new Param
+ param.name = "UNKNOWN"
+ param.return_type = "UNKNOWN"
+ param.variable_name = "UNKNOWN"
+ end
+
+ method.params.add param
+ end
+
+ v.objc_class.methods.add method
+ end
+end
+
+# Class variable/attribute declaration (inside alternative node)
+redef class Nproperty_property
+ redef fun accept_objc(v)
+ do
+ var attr = new ObjcAttribute
+ attr.return_type = n_type.to_type
+ attr.name = n_left.collect_text
+
+ v.objc_class.attributes.add attr
+ end
+end
+
+# Class variable/attribute declaration (outside with @property)
+redef class Nproperty_declaration_property
+ redef fun accept_objc(v)
+ do
+ # TODO property attribute readonly, copy, etc.
+ super
+ end
+end
+
+# ---
+# Support nodes
+
+redef class NProd
+ # Append all tokens under this node in a `String`
+ private fun collect_text: String
+ do
+ var buf = new FlatBuffer
+ for node in depth do if node isa NToken then buf.append node.text
+ return buf.to_s
+ end
+end
+
+redef class Nlines
+ # Do not visit other lines, they are only to be eaten
+ redef fun accept_objc(v) do end
+end
+
+redef class Nscope
+ # Does this mark a class property (+)? Otherwise it's an instance property (-).
+ private fun is_class_property: Bool do return false
+end
+
+redef class Nscope_class
+ redef fun is_class_property do return true
+end
+
+redef class Nsignature_return_type
+ # Get type from this node TODO return an ObjcType
+ private fun to_type: String do return collect_text
+end
+
+redef class Nsignature_return_type_return
+ redef fun to_type do return n_type.to_type
+end
+
+redef class Nparameter
+ # Return null if type is not yet unsupported
+ private fun to_param: nullable Param do return null
+end
+
+# Parameters with both a public and an internal name
+redef class Nparameter_named
+ redef fun to_param
+ do
+ var param = new Param
+ param.variable_name = n_right.collect_text
+ param.name = n_left.collect_text
+ param.return_type = n_parameter_type.to_type
+ return param
+ end
+end
+
+# Usually the name of a method without parameters
+redef class Nparameter_single
+ redef fun to_param
+ do
+ var param = new Param
+ param.name = n_term.collect_text
+ param.is_single = true
+ return param
+ end
+end
+
+redef class Nparameter_type
+ # Get type from this node TODO return an ObjcType
+ private fun to_type: String
+ do
+ # FIXME taking the first token skips pointers
+ for child in children do
+ if child isa Ntype then
+ return child.to_type
+ end
+ end
+
+ return collect_text
+ end
+end
+
+redef class Ntype
+ # Get type from this node TODO return an ObjcType
+ private fun to_type: String do return collect_text
+end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Generator of Nit modules to wrap Objective-C services
+module objcwrapper
+
+import nitcc_runtime
+import opts
+
+import objc_visitor
+import objc_model
+import objc_generator
+import objc_lexer
+import objc_parser
+
+var opt_help = new OptionBool("Show this help message", "-h", "--help")
+
+var opts = new OptionContext
+opts.add_option(opt_help, opt_output)
+opts.parse(args)
+
+if opts.errors.not_empty or opts.rest.is_empty or opt_help.value then
+ print """
+Usage: objcwrapper [options] input_file [other_input_file [...]]
+Options:"""
+ opts.usage
+
+ if opt_help.value then exit 0
+ exit 1
+end
+
+var v = new ObjcVisitor
+var g = new CodeGenerator
+
+for arg in opts.rest do
+ # Read input
+ var content = arg.to_path.read_all
+
+ # Parse
+ var lexer = new Lexer_objc(content)
+ var parser = new Parser_objc
+ var tokens = lexer.lex
+ parser.tokens.add_all(tokens)
+ var root = parser.parse
+
+ # Check for errors
+ if root isa NError then
+ print_error "Syntax Error: {root.message}: {root.position or else ""}"
+ continue
+ end
+
+ # Run analysis
+ v.enter_visit root
+end
+
+g.generate v.model.classes
--- /dev/null
+@interface MyClass : NSObject
+ <NSCoding, NSCopying, NSMutableCopying, NSFastEnumeration>
+
++ (id) array;
++ (id) arrayWithContentsOfFile: (NSString*)file;
+
+- (id) arrayWithArray: (MyClass*)array;
+
+@property (readonly) NSUInteger count;
+@property NSUInteger head;
+
+@end
if (!lib_files_loaded)
{
// We get the 'nit' folder content on github.
- $.get("https://api.github.com/repos/privat/nit/contents/?access_token=" + github_acces_token, function(data) {
+ $.get("https://api.github.com/repos/nitlang/nit/contents/?access_token=" + github_acces_token, function(data) {
for (var i = 0; i < data.length; i++) {
if (data[i].name == "lib") {
// We get the list of all files in the 'lib' folder.
- $.get("https://api.github.com/repos/privat/nit/git/trees/" + data[i].sha + "?recursive=1&access_token=" + github_acces_token, function(data) {
+ $.get("https://api.github.com/repos/nitlang/nit/git/trees/" + data[i].sha + "?recursive=1&access_token=" + github_acces_token, function(data) {
for (var i = 0; i < data.tree.length; i++) {
if (data.tree[i].type == "blob") {
lib_files_number++;
Opportunity is a web-application written in Nit to plan meetups with people in real-life (or on the internet, why not !).
-It runs on Nit's official web server: Nitcorn, available along with the compiler for the language on Github <https://github.com/privat/nit>.
+It runs on Nit's official web server: Nitcorn, available along with the compiler for the language on Github <https://github.com/nitlang/nit>.
# Compile and execute
</ul>
<ul class="nav navbar-nav pull-right">
- <li><a href="https://github.com/privat/nit/tree/master/contrib/pep8analysis/">Source and manual</a></li>
+ <li><a href="https://github.com/nitlang/nit/tree/master/contrib/pep8analysis/">Source and manual</a></li>
<li><a href="https://code.google.com/p/pep8-1/">Pep/8 project</a></li>
</ul>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
- <li><a href="https://github.com/privat/nit/">Nit repository</a></li>
+ <li><a href="https://github.com/nitlang/nit/">Nit repository</a></li>
</ul>
<ul class="nav navbar-nav pull-right">
<div class="container">
<h1>Fibonacci calculator</h1>
- <a href="https://github.com/privat/nit/blob/master/examples/fibonacci.nit">Nit source</a><br>
- <a href="https://github.com/privat/nit/blob/master/examples/emscripten/fibonacci/www/index.html">HTML source</a>
+ <a href="https://github.com/nitlang/nit/blob/master/examples/fibonacci.nit">Nit source</a><br>
+ <a href="https://github.com/nitlang/nit/blob/master/examples/emscripten/fibonacci/www/index.html">HTML source</a>
<h2>Status</h2>
<p id="loading">Loading...</p>
License:Apache2
Web Site:http://nitlanguage.org
Source Code:http://nitlanguage.org/nit.git/tree/HEAD:/examples/mnit_ballz
-Issue Tracker:https://github.com/privat/nit/issues
+Issue Tracker:https://github.com/nitlang/nit/issues
Summary:A Sensor Demo
Description:
License:Apache2
Web Site:http://nitlanguage.org
Source Code:http://nitlanguage.org/nit.git/tree/HEAD:/examples/mnit_dino
-Issue Tracker:https://github.com/privat/nit/issues
+Issue Tracker:https://github.com/nitlang/nit/issues
Summary:Tactical arcade game
Description:
License:Apache2
Web Site:http://nitlanguage.org
Source Code:http://nitlanguage.org/nit.git/tree/HEAD:/examples/mnit_simple
-Issue Tracker:https://github.com/privat/nit/issues
+Issue Tracker:https://github.com/nitlang/nit/issues
Summary:Simple Demo for MNit
Description:
License:Apache2
Web Site:http://nitlanguage.org
Source Code:http://nitlanguage.org/nit.git/tree/HEAD:/examples/shoot
-Issue Tracker:https://github.com/privat/nit/issues
+Issue Tracker:https://github.com/nitlang/nit/issues
Summary:A shoot'em up in space
Description:
# The API client allows you to get Github API entities.
#
# ~~~
-# var repo = api.load_repo("privat/nit")
+# var repo = api.load_repo("nitlang/nit")
# assert repo != null
# assert repo.name == "nit"
#
# See other `load_*` methods to use more expressive types.
#
# var api = new GithubAPI(get_github_oauth)
- # var obj = api.get("repos/privat/nit")
+ # var obj = api.get("repos/nitlang/nit")
# assert obj isa JsonObject
# assert obj["name"] == "nit"
#
# Loads the `Repo` from the API or returns `null` if the repo cannot be found.
#
# var api = new GithubAPI(get_github_oauth)
- # var repo = api.load_repo("privat/nit")
+ # var repo = api.load_repo("nitlang/nit")
# assert repo.name == "nit"
- # assert repo.owner.login == "privat"
+ # assert repo.owner.login == "nitlang"
# assert repo.default_branch.name == "master"
fun load_repo(full_name: String): nullable Repo do
var repo = new Repo(self, full_name)
# Returns `null` if the branch cannot be found.
#
# var api = new GithubAPI(get_github_oauth)
- # var repo = api.load_repo("privat/nit")
+ # var repo = api.load_repo("nitlang/nit")
# assert repo != null
# var branch = api.load_branch(repo, "master")
# assert branch.name == "master"
# Returns `null` if the commit cannot be found.
#
# var api = new GithubAPI(get_github_oauth)
- # var repo = api.load_repo("privat/nit")
+ # var repo = api.load_repo("nitlang/nit")
# assert repo != null
# var commit = api.load_commit(repo, "64ce1f")
# assert commit isa Commit
# Returns `null` if the issue cannot be found.
#
# var api = new GithubAPI(get_github_oauth)
- # var repo = api.load_repo("privat/nit")
+ # var repo = api.load_repo("nitlang/nit")
# assert repo != null
# var issue = api.load_issue(repo, 1)
# assert issue.title == "Doc"
# Returns `null` if the pull request cannot be found.
#
# var api = new GithubAPI(get_github_oauth)
- # var repo = api.load_repo("privat/nit")
+ # var repo = api.load_repo("nitlang/nit")
# assert repo != null
# var pull = api.load_pull(repo, 1)
# assert pull.title == "Doc"
# Returns `null` if the label cannot be found.
#
# var api = new GithubAPI(get_github_oauth)
- # var repo = api.load_repo("privat/nit")
+ # var repo = api.load_repo("nitlang/nit")
# assert repo != null
# var labl = api.load_label(repo, "ok_will_merge")
# assert labl != null
# Returns `null` if the milestone cannot be found.
#
# var api = new GithubAPI(get_github_oauth)
- # var repo = api.load_repo("privat/nit")
+ # var repo = api.load_repo("nitlang/nit")
# assert repo != null
# var stone = api.load_milestone(repo, 4)
# assert stone.title == "v1.0prealpha"
# Returns `null` if the event cannot be found.
#
# var api = new GithubAPI(get_github_oauth)
- # var repo = api.load_repo("privat/nit")
+ # var repo = api.load_repo("nitlang/nit")
# assert repo isa Repo
# var event = api.load_issue_event(repo, 199674194)
# assert event.actor.login == "privat"
# Returns `null` if the comment cannot be found.
#
# var api = new GithubAPI(get_github_oauth)
- # var repo = api.load_repo("privat/nit")
+ # var repo = api.load_repo("nitlang/nit")
# assert repo != null
# var comment = api.load_commit_comment(repo, 8982707)
# assert comment.user.login == "Morriar"
# Returns `null` if the comment cannot be found.
#
# var api = new GithubAPI(get_github_oauth)
- # var repo = api.load_repo("privat/nit")
+ # var repo = api.load_repo("nitlang/nit")
# assert repo != null
# var comment = api.load_issue_comment(repo, 6020149)
# assert comment.user.login == "privat"
# Returns `null` if the comment cannot be found.
#
# var api = new GithubAPI(get_github_oauth)
- # var repo = api.load_repo("privat/nit")
+ # var repo = api.load_repo("nitlang/nit")
# assert repo != null
# var comment = api.load_review_comment(repo, 21010363)
# assert comment.path == "src/modelize/modelize_property.nit"
# var api = new GithubAPI(get_github_oauth)
# api.enable_cache = true
#
-# var name = "privat/nit"
+# var name = "nitlang/nit"
# assert not api.has_cache(name)
# var repo = api.load_repo(name) # load from GitHub
# #assert api.has_cache(name) FIXME bring back this assert
end
fun test_get_repo do
- var uri = "https://api.github.com/repos/privat/nit"
+ var uri = "https://api.github.com/repos/nitlang/nit"
var res = testee.get_and_check(uri)
assert res isa JsonObject
# # Then call "dot -Tpng -o graph.png"
# ~~~
#
-# ![A graph drawing produced by Graphviz](https://github.com/privat/nit/blob/master/lib/graph.png)
+# ![A graph drawing produced by Graphviz](https://github.com/nitlang/nit/blob/master/lib/graph.png)
#
# Other methods
# =============
# and a cause of bugs.
#
# Without redefinition, `hash` is based on the `object_id` of the instance.
- fun hash: Int do return object_id / 8
+ fun hash: Int do return object_id
end
# The main class of the program.
For instance, the [standard library] use the following value to link to files in GitHub:
- "https://github.com/privat/nit/blob/$(git rev-parse HEAD)/%f#L%l-%L"
+ "https://github.com/nitlang/nit/blob/$(git rev-parse HEAD)/%f#L%l-%L"
Here, the `git rev-parse HEAD` is used to link to the current snapshot revision of the file.