Here's a patch with a hack fix to the problem. Basically, I just
added another branch to the cond expression on line 692. It just
expands the include filename with respect to the first element in
semantidbd-project-roots. Obviously, not a real solution, but it
demonstrates at least one approach.
=== modified file 'semantic/semanticdb-find.el'
*** semantic/semanticdb-find.el 2011-10-06 17:13:59 +0000
--- semantic/semanticdb-find.el 2011-10-17 06:17:56 +0000
***************
*** 690,695 ****
--- 690,697 ----
(let* ((ref (if (slot-boundp (car roots) 'reference-directory)
(oref (car roots) reference-directory)))
(fname (cond ((null ref) nil)
+ ((file-exists-p (expand-file-name name (concat (car
semanticdb-project-roots) "/")))
+ (expand-file-name name (concat (car semanticdb-project-roots) "/")))
((file-exists-p (expand-file-name name ref))
(expand-file-name name ref))
((file-exists-p (expand-file-name (file-name-nondirectory name) ref))
***************
*** 697,703 ****
(when (and ref fname)
;; There is an actual file. Grab it.
(setq ans (semanticdb-find-load-unloaded fname)))
!
;; ELSE
;;
;; NOTE: We used to look up omniscient databases here, but that
--- 699,705 ----
(when (and ref fname)
;; There is an actual file. Grab it.
(setq ans (semanticdb-find-load-unloaded fname)))
!
;; ELSE
;;
;; NOTE: We used to look up omniscient databases here, but that
On Sun, Oct 16, 2011 at 10:43 PM, David Ventimiglia <dventimi@...> wrote:
> Hi,
>
> I'm starting to think perhaps there's a bug, possibly in
> semanticdb-find.el (though possibly elsewhere), at least for Java.
> The problem is this. semantic-tag-include-filename for Java
> (overridden in semantic-java.el) replaces periods (.) with forward
> slashes (/), and sticks ".java" on the end. So "import
> server.Server;" translates to "server/Server.java". Seems reasonable.
> But then in semanticdb-find-table-for-include-default (in
> semanticdb-find.el), toward the end of the defun it loops over "roots"
> (tables, I guess) returned by semanticdb-current-database-list, fishes
> out the "reference directory" for each such table, forms a
> fully-qualified filepath from the filename of the import
> ("server/Server.java" in my example) and that reference directory. I
> turns out that the only table in "roots" is for the file we're in (the
> one we're parsing, which is the one that contains the "import"
> statement, which in my example is "client/Client.java") and its
> reference directory is "../src/client/". So the expanded filename
> it's looking for, for the include, is in my example
> "../src/client/server/Server.java", which is definitely wrong. No
> such file exists, and so the lookup silently fails. The file it
> should be looking for, in my example, is "../src/server/Server.java".
> In other words, it's resolving the relative pathname corresponding to
> the "include" ("server/Server.java" in my case) with respect to the
> path of the including file, rather than with respect to the project
> root.
>
> Now, I'm not sure what the correct behavior should be for C/C++ and
> other languages that do "includes", but for Java, I think it should
> always resolve the relative pathnames for "includes" with respect to
> the project root. If you're using EDE, then I think a file would
> belong to just one project, and the EDE routines would find just that
> one project and return the correct root. But even if you're not using
> EDE, and you just set semanticdb-project-roots, in the worst case if
> it looked for the relative pathname of the "include" with respect to
> each of the semanticdb-project-roots it would silently fail for all
> but one (the correct one). Well, I guess the worst case would be if
> that include filename existed in several different
> semanticdb-project-roots values. I guess that would be a argument in
> favor of using the more sophisticated EDE. But that's besides the
> point.
>
> I know that this--as written--looks a bit complicated, so I'll try to
> summarize. The function semanticdb-find-table-for-include-default
> tries to resolve the relative filenames corresponding to Java "import"
> statements with respect to the including file. This is wrong. It
> probably* should be resolving them with respect to the project root.
>
> Cheers,
> David
>
> *Note: It's actually even more complicated than this, for a variety of reasons.
> 1. Nothing in the "contract" or API of semanticdb leads me to believe
> that semanticdb-project-roots has to support resolving filenames of
> "include" statements. It seems mainly (or only) about throttling
> searches. For instance, in my example, there's no reason the one
> value in semanticdb-project-roots has to end in "../src". The user
> might set it to be higher up in the directory structure, which would
> complicate things. The meaning of semanticdb-project-roots could be
> changed to "absolute pathname with respect to which relative pathnames
> for includes will be resolved", but that would be a significant change
> and I don't know what repurcussions it would have for semanticdb.
> 2. I believe Java does not actually require that package structures
> (e.g., "server.Server") maps one-to-one to directory structures (e.g.,
> "server/Server.java"), though that is the universal convention. It's
> slightly more than just a convention since, if you don't specify
> included files on the command-line when compiling Java sources, the
> compiler will (typically) guess their location in this way. In
> addition, emitted .class files will be organized this way. BUT, if
> you specify all the related files together on the command-line, they
> can be anywhere.
> 3. To sum up, a quick and dirty solution that probably would cover 99%
> to 100% of cases would be to resolve Java "includes" with respect to
> the semanticdb-project-roots. A slightly better solution would be to
> leave semanticdb-project-roots intact, and introduce some other
> variable to serve the resolving purpose. The "correct" solution would
> require a central database of all encountered Java files, indexed by
> their package. This is probably overkill.
>
>
> On Sun, Oct 9, 2011 at 10:22 PM, David Ventimiglia <dventimi@...> wrote:
>> Hi!
>>
>> After struggling to get semanticdb-global to work properly, I
>> retreated to a simpler configuration using fewer working parts.
>> Unfortunately, I'm still running into trouble, and the problem is
>> this. Tags cached onto disk by semanticdb seem not to get loaded, or
>> loaded correctly, at least for Java. This is something I inferred
>> after running the following experiment, using GNU Emacs 24.0.50.1 on
>> Ubuntu Linux.
>>
>> 1. Downloaded the bzr repository version of CEDET, getting the latest
>> code as of 10/8/2011.
>> 2. Compiled it using `make'.
>> 3. Loaded it, turned on some coding helpers, and set up semanticdb
>> project roots with these commands in my .emacs file.
>> (load-file "~/work/cedet/common/cedet.el")
>> (semantic-load-enable-excessive-code-helpers)
>> (semantic-load-enable-semantic-debugging-helpers)
>> (add-to-list 'semanticdb-project-roots (expand-file-name
>> "~/work/semantic-java-test/src"))
>> 4. Opened $HOME/work/semantic-java-test/src/server/Server.java.
>> 5. Opened $HOME/work/semantic-java-test/src/client/Client.java, which
>> has one import statement `import server.Server;'.
>> 6. Noticed that in Client.java, the import statement `import
>> server.Server;' is highlighted in green, and when I right-click on it
>> and choose "What is this?", I get a buffer with the following
>> contents.
>> Include Tag: server.Server
>>
>> This header tag has been marked "Fileless".
>> This means that Semantic cannot find a file associated with this tag
>> on disk, but a database table of tags has been associated with it.
>>
>> This means that the include will still be used to find tags for
>> searches, but you connot visit this include.
>>
>> This Header is now represented by the following database table:
>>
>> #<semanticdb-table Server.java (2 tags)>
>> 7. Closed Emacs, then looked in $HOME/.semanticdb and see
>> semantic.cache files for both the `server' and `client' directories.
>> 8. Opened Emacs then opened $HOME/work/semantic-java-test/src/Client.java.
>> 9. Noticed that in Client.java, the import statement now is
>> highlighted in pink, and when I right-click on it and choose "What is
>> this?", I get a buffer with the following.
>> Include File: server.Server
>>
>> This header file has been marked "Unknown".
>> This means that Semantic has not been able to locate this file on disk.
>>
>> When Semantic cannot find an include file, this means that the
>> idle summary mode and idle completion modes cannot use the contents of
>> that file to provide coding assistance.
>>
>> If this is a system header and you want it excluded from Semantic's
>> searches (which may be desirable for speed reasons) then you can
>> safely ignore this state.
>>
>> If this is a system header, and you want to include it in Semantic's
>> searches, then you will need to use:
>>
>> M-x semantic-add-system-include RET /path/to/includes RET
>>
>> or, in your .emacs file do:
>>
>> (semantic-add-system-include "/path/to/include" 'java-mode)
>>
>> to add the path to Semantic's search.
>>
>> If this is an include file that belongs to your project, then you may
>> need to update `semanticdb-project-roots' or better yet, use `ede'
>> to manage your project. See the ede manual for projects that will
>> wrap existing project code for Semantic's benifit.
>>
>> See the Semantic manual node on SemanticDB for more about search paths.
>>
>>
>> QUESTIONS:
>> 1. I thought semanticdb would load tags from the semantic.cache files
>> (if they exist) for Server.java, and so would figure out the import
>> statement in Client.java without having to re-parse Server.java. Do I
>> understand this correctly?
>> 2. If that's the case, then it seems not to be working correctly. Is
>> that a fair assessment?
>> 3. Maybe I've mis-configured it. My extremely spartan .emacs file is
>> pasted in again below. Is there more to it than just loading CEDET,
>> turning on some code helpers, and creating a project root?
>> 4. If it's actually broken, where do I need to start looking in the
>> semantic code to debug this?
>> 5. (side issue). Even when semantic figures out the import statement
>> in Client.java (i.e., when I re-parse Server.java by visiting that
>> file), it says it's been marked "Fileless". What exactly does that
>> mean? Does this also indicate a problem?
>>
>> I'd love it if someone else would run the same or a similar experiment
>> to see if they get the same or similar results. I would love to solve
>> this puzzle since if I can get semantic working smoothly with Java
>> code I'll be able to ditch IntelliJ. :)
>>
>> Thanks!
>> Cheers,
>> David
>>
>> P.S. Here's my .emacs file
>> (load-file "~/work/cedet/common/cedet.el")
>> (semantic-load-enable-excessive-code-helpers)
>> (semantic-load-enable-semantic-debugging-helpers)
>> (add-to-list 'semanticdb-project-roots (expand-file-name
>> "~/work/semantic-java-test/src"))
>>
>> P.P.S. Here're Server.java and Client.java
>> package server;
>> public class Server {
>> public void serve () {}
>> }
>> --------------------------------------------
>> package client;
>> import server.Server;
>> public class Client {
>> public void doWork () {
>> Server s = new Server();
>> }
>> }
>>
>
|