diff --git a/src/arduino.cc/builder/ctags_parser.go b/src/arduino.cc/builder/ctags_parser.go index e0448dcb..d0773196 100644 --- a/src/arduino.cc/builder/ctags_parser.go +++ b/src/arduino.cc/builder/ctags_parser.go @@ -77,6 +77,7 @@ func (s *CTagsParser) Run(context map[string]interface{}) error { tags = addPrototypes(tags) tags = removeDefinedProtypes(tags) tags = removeDuplicate(tags) + tags = skipTagsWhere(tags, prototypeAndCodeDontMatch) if len(tags) > 0 { line, err := strconv.Atoi(tags[0][FIELD_LINE]) @@ -172,6 +173,28 @@ func signatureContainsDefaultArg(tag map[string]string) bool { return strings.Contains(tag[FIELD_SIGNATURE], "=") } +func prototypeAndCodeDontMatch(tag map[string]string) bool { + if tag[FIELD_SKIP] == "true" { + return true + } + + code := removeSpacesAndTabs(tag[FIELD_CODE]) + prototype := removeSpacesAndTabs(tag[KIND_PROTOTYPE]) + prototype = removeTralingSemicolon(prototype) + + return strings.Index(code, prototype) != 0 +} + +func removeTralingSemicolon(s string) string { + return s[0 : len(s)-1] +} + +func removeSpacesAndTabs(s string) string { + s = strings.Replace(s, " ", "", -1) + s = strings.Replace(s, "\t", "", -1) + return s +} + func filterOutTagsWithField(tags []map[string]string, field string) []map[string]string { var newTags []map[string]string for _, tag := range tags { diff --git a/src/arduino.cc/builder/test/ctags_output/TestCTagsParserFunctionPointers.txt b/src/arduino.cc/builder/test/ctags_output/TestCTagsParserFunctionPointers.txt new file mode 100644 index 00000000..0aa1e06a --- /dev/null +++ b/src/arduino.cc/builder/test/ctags_output/TestCTagsParserFunctionPointers.txt @@ -0,0 +1,5 @@ +setup /tmp/test907446433/preproc/ctags_target.cpp /^void setup(){$/;" kind:function line:2 signature:() returntype:void +loop /tmp/test907446433/preproc/ctags_target.cpp /^void loop(){}$/;" kind:function line:5 signature:() returntype:void +func /tmp/test907446433/preproc/ctags_target.cpp /^void (*func())(){$/;" kind:function line:7 signature:() returntype:void +funcArr /tmp/test907446433/preproc/ctags_target.cpp /^int (&funcArr())[5]{$/;" kind:function line:11 signature:() returntype:int +funcCombo /tmp/test907446433/preproc/ctags_target.cpp /^void (*(&funcCombo(void (*(&in)[5])(int)))[5])(int){$/;" kind:function line:15 signature:(void (*(&in)[5])(int)) returntype:void diff --git a/src/arduino.cc/builder/test/ctags_parser_test.go b/src/arduino.cc/builder/test/ctags_parser_test.go index 441c0ba9..298e8a72 100644 --- a/src/arduino.cc/builder/test/ctags_parser_test.go +++ b/src/arduino.cc/builder/test/ctags_parser_test.go @@ -243,3 +243,21 @@ func TestCTagsParserNamespace(t *testing.T) { require.Equal(t, "void setup();", prototypes[0].Prototype) require.Equal(t, "void loop();", prototypes[1].Prototype) } + +func TestCTagsParserFunctionPointers(t *testing.T) { + context := make(map[string]interface{}) + + bytes, err := ioutil.ReadFile(filepath.Join("ctags_output", "TestCTagsParserFunctionPointers.txt")) + NoError(t, err) + + context[constants.CTX_CTAGS_OUTPUT] = string(bytes) + + ctagsParser := builder.CTagsParser{PrototypesField: constants.CTX_PROTOTYPES} + ctagsParser.Run(context) + + prototypes := context[constants.CTX_PROTOTYPES].([]*types.Prototype) + + require.Equal(t, 2, len(prototypes)) + require.Equal(t, "void setup();", prototypes[0].Prototype) + require.Equal(t, "void loop();", prototypes[1].Prototype) +} diff --git a/src/arduino.cc/builder/test/prototypes_adder_test.go b/src/arduino.cc/builder/test/prototypes_adder_test.go index 996b5554..34555e4c 100644 --- a/src/arduino.cc/builder/test/prototypes_adder_test.go +++ b/src/arduino.cc/builder/test/prototypes_adder_test.go @@ -495,7 +495,7 @@ func TestPrototypesAdderSketchNoFunctions(t *testing.T) { require.Nil(t, context[constants.CTX_PROTOTYPE_SECTION]) } -func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { +func TestPrototypesAdderSketchComplexFunctions(t *testing.T) { DownloadCoresAndToolsAndLibraries(t) context := make(map[string]interface{}) @@ -506,7 +506,7 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_default_args", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_complex_prototypes", "sketch.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -533,10 +533,10 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void setup();\nvoid loop();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "void setup();\nvoid loop();\nshort unsigned int testSimple();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } -func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { +func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { DownloadCoresAndToolsAndLibraries(t) context := make(map[string]interface{}) @@ -547,11 +547,11 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_inline_function", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_function_signature_inside_ifdef", "sketch.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} - context[constants.CTX_VERBOSE] = false + context[constants.CTX_VERBOSE] = true commands := []types.Command{ &builder.SetupHumanLoggerIfMissing{}, @@ -574,10 +574,10 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void setup();\nvoid loop();\nshort unsigned int testInt();\nint8_t testInline();\nuint8_t testAttribute();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "void setup();\nvoid loop();\nint8_t adalight();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } -func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { +func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { DownloadCoresAndToolsAndLibraries(t) context := make(map[string]interface{}) @@ -588,7 +588,7 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_function_signature_inside_ifdef", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_usbcon", "sketch.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} @@ -615,10 +615,10 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void setup();\nvoid loop();\nint8_t adalight();\n#line 1\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "void ciao();\nvoid setup();\nvoid loop();\n#line 3\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } -func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { +func TestPrototypesAdderSketchWithTypename(t *testing.T) { DownloadCoresAndToolsAndLibraries(t) context := make(map[string]interface{}) @@ -629,10 +629,9 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"} context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"} context[constants.CTX_FQBN] = "arduino:avr:leonardo" - context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_usbcon", "sketch.ino") + context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_typename", "sketch.ino") context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600" - context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"} - context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"} + context[constants.CTX_LIBRARIES_FOLDERS] = []string{"libraries", "downloaded_libraries"} context[constants.CTX_VERBOSE] = true commands := []types.Command{ @@ -656,5 +655,5 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) { } require.Equal(t, "#include \n#line 1\n", context[constants.CTX_INCLUDE_SECTION].(string)) - require.Equal(t, "void ciao();\nvoid setup();\nvoid loop();\n#line 3\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) + require.Equal(t, "void setup();\nvoid loop();\n#line 6\n", context[constants.CTX_PROTOTYPE_SECTION].(string)) } diff --git a/src/arduino.cc/builder/test/sketch_with_inline_function/sketch.ino b/src/arduino.cc/builder/test/sketch_with_complex_prototypes/sketch.ino similarity index 57% rename from src/arduino.cc/builder/test/sketch_with_inline_function/sketch.ino rename to src/arduino.cc/builder/test/sketch_with_complex_prototypes/sketch.ino index f0a25e69..a55579ac 100644 --- a/src/arduino.cc/builder/test/sketch_with_inline_function/sketch.ino +++ b/src/arduino.cc/builder/test/sketch_with_complex_prototypes/sketch.ino @@ -1,7 +1,7 @@ void setup() {} void loop() {} -short unsigned int testInt(){ +short unsigned int testSimple(){ } @@ -12,3 +12,11 @@ static inline int8_t testInline(){ __attribute__((always_inline)) uint8_t testAttribute() { } + +void testDefault(int x = 1) { + +} + +static void testStatic() { + +} diff --git a/src/arduino.cc/builder/test/sketch_with_default_args/sketch.ino b/src/arduino.cc/builder/test/sketch_with_default_args/sketch.ino deleted file mode 100644 index 6a5ee7cc..00000000 --- a/src/arduino.cc/builder/test/sketch_with_default_args/sketch.ino +++ /dev/null @@ -1,8 +0,0 @@ -void test(int x = 1) { -} - -void setup() { -} - -void loop() { -} \ No newline at end of file