mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-12-08 20:38:47 +00:00
More robust heuristics for .m files and 3 new Matlab tests. Support for Obj-C detection fully intact; all tests pass. Detection of Obj-C keywords @implementation, @property, @interface, and @synthesize removed to avoid possible conflicts with user-created Matlab function handles. Only @end is needed, which is not valid in Matlab. Matlab class files supported. Comments preceded by whitespace detected for Obj-C and Matlab.
Signed-off-by: Andrew D. Horchler <adh9@case.edu>
This commit is contained in:
@@ -451,24 +451,26 @@ module Linguist
|
|||||||
# Internal: Guess language of .m files.
|
# Internal: Guess language of .m files.
|
||||||
#
|
#
|
||||||
# Objective-C heuristics:
|
# Objective-C heuristics:
|
||||||
# * Keywords
|
# * Keywords ("#import", "#include", "#ifdef", #define, "@end") or "//" and opening "\*" comments
|
||||||
#
|
#
|
||||||
# Matlab heuristics:
|
# Matlab heuristics:
|
||||||
# * Leading function keyword
|
# * Leading "function " of "classdef " keyword
|
||||||
# * "%" comments
|
# * "%" comments
|
||||||
#
|
#
|
||||||
|
# Note: All "#" keywords, e.g., "#import", are guaranteed to be Objective-C. Because the ampersand
|
||||||
|
# is used to created function handles and anonymous functions in Matlab, most "@" keywords are not
|
||||||
|
# safe heuristics. However, "end" is a reserved term in Matlab and can't be used to create a valid
|
||||||
|
# function handle. Because @end is required to close any @implementation, @property, @interface,
|
||||||
|
# @synthesize, etc. directive in Objective-C, only @end needs to be checked for.
|
||||||
|
#
|
||||||
# Returns a Language.
|
# Returns a Language.
|
||||||
def guess_m_language
|
def guess_m_language
|
||||||
# Objective-C keywords
|
# Objective-C keywords or comments
|
||||||
if lines.grep(/^#import|@(interface|implementation|property|synthesize|end)/).any?
|
if lines.grep(/^#(import|include|ifdef|define)|@end/).any? || lines.grep(/^\s*\/\//).any? || lines.grep(/^\s*\/\*/).any?
|
||||||
Language['Objective-C']
|
Language['Objective-C']
|
||||||
|
|
||||||
# File function
|
# Matlab file function or class or comments
|
||||||
elsif lines.first.to_s =~ /^function /
|
elsif lines.first.grep(/^\s*(function |classdef )/).any? || lines.grep(/^\s*%/).any?
|
||||||
Language['Matlab']
|
|
||||||
|
|
||||||
# Matlab comment
|
|
||||||
elsif lines.grep(/^%/).any?
|
|
||||||
Language['Matlab']
|
Language['Matlab']
|
||||||
|
|
||||||
# Fallback to Objective-C, don't want any Matlab false positives
|
# Fallback to Objective-C, don't want any Matlab false positives
|
||||||
|
|||||||
29
test/fixtures/matlab_class.m
vendored
Normal file
29
test/fixtures/matlab_class.m
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
classdef matlab_class
|
||||||
|
properties
|
||||||
|
R;
|
||||||
|
G;
|
||||||
|
B;
|
||||||
|
end
|
||||||
|
methods
|
||||||
|
function obj = matlab_class(r,g,b)
|
||||||
|
obj.R = r;
|
||||||
|
obj.G = g;
|
||||||
|
obj.B = b;
|
||||||
|
end
|
||||||
|
function disp(obj)
|
||||||
|
disp(['Red: ' num2str(obj.R) ...
|
||||||
|
', Green: ' num2str(obj.G) ...
|
||||||
|
', Blue: ' num2str(obj.B)]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
enumeration
|
||||||
|
red (1,0,0)
|
||||||
|
green (0,1,0)
|
||||||
|
blue (0,0,1)
|
||||||
|
cyan (0,1,1)
|
||||||
|
magenta (1,0,1)
|
||||||
|
yellow (1,1,0)
|
||||||
|
black (0,0,0)
|
||||||
|
white (1,1,1)
|
||||||
|
end
|
||||||
|
end
|
||||||
33
test/fixtures/matlab_function2.m
vendored
Normal file
33
test/fixtures/matlab_function2.m
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
function ret = matlab_function2(A,B)
|
||||||
|
% Simple function that combines two values using function handles and displays
|
||||||
|
% the return value
|
||||||
|
|
||||||
|
% create function handles
|
||||||
|
fun1=@interface;
|
||||||
|
fun2=@implementation;
|
||||||
|
fun3=@property;
|
||||||
|
fun4=@synthesize;
|
||||||
|
|
||||||
|
% use function handles
|
||||||
|
ret = fun1(A)+fun2(A)+fun3(B)+fun4(B);
|
||||||
|
|
||||||
|
% Display the return value
|
||||||
|
disp('Return value in function');
|
||||||
|
disp(ret);
|
||||||
|
|
||||||
|
|
||||||
|
function A=interface(A)
|
||||||
|
% simple sub-function with same name Objective-C @keyword
|
||||||
|
A=2*A;
|
||||||
|
|
||||||
|
function A=implementation(A)
|
||||||
|
% simple sub-function with same name Objective-C @keyword
|
||||||
|
A=A^2;
|
||||||
|
|
||||||
|
function B=property(B)
|
||||||
|
% simple sub-function with same name Objective-C @keyword
|
||||||
|
B=2*B;
|
||||||
|
|
||||||
|
function B=synthesize(B)
|
||||||
|
% simple sub-function with same name Objective-C @keyword
|
||||||
|
B=B^2;
|
||||||
13
test/fixtures/matlab_script2.m
vendored
Normal file
13
test/fixtures/matlab_script2.m
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
% Matlab example script 2
|
||||||
|
% Comments precended with arbitrary whitespace (spaces or tabs)
|
||||||
|
|
||||||
|
%Call matlab_function function which resides in the same directory
|
||||||
|
|
||||||
|
value1 = 5 % semicolon at end of line is not mandatory, only suppresses output to command line.
|
||||||
|
value2 = 3
|
||||||
|
|
||||||
|
% Calculate sum of value1 and value2
|
||||||
|
result = matlab_function(value1,value2);
|
||||||
|
|
||||||
|
disp('called from script')
|
||||||
|
disp(result);
|
||||||
@@ -311,6 +311,9 @@ class TestBlob < Test::Unit::TestCase
|
|||||||
assert_equal Language['Objective-C'], blob("hello.m").language
|
assert_equal Language['Objective-C'], blob("hello.m").language
|
||||||
assert_equal Language['Matlab'], blob("matlab_function.m").language
|
assert_equal Language['Matlab'], blob("matlab_function.m").language
|
||||||
assert_equal Language['Matlab'], blob("matlab_script.m").language
|
assert_equal Language['Matlab'], blob("matlab_script.m").language
|
||||||
|
assert_equal Language['Matlab'], blob("matlab_function2.m").language
|
||||||
|
assert_equal Language['Matlab'], blob("matlab_script2.m").language
|
||||||
|
assert_equal Language['Matlab'], blob("matlab_class.m").language
|
||||||
|
|
||||||
# .r disambiguation
|
# .r disambiguation
|
||||||
assert_equal Language['R'], blob("hello-r.R").language
|
assert_equal Language['R'], blob("hello-r.R").language
|
||||||
|
|||||||
Reference in New Issue
Block a user