[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-dev] BindingProblems on the StandaloneIndexer

Hi, I'm using the StandaloneIndexer to index code and ran into a
BindingProblem where it can't create a scope.
I think I've narrowed it down the simplest possible case.
I'm not sure if I set things up wrong or not.  It doesn't seem like this
would be a bug in the Indexer itself.
[still not sure if I should be using GeneratedPDOMApplication or not]

I have 4 four files:
  file1.h: trivial class declartation
  file1.cc:  file that implements that class
             It includes file1.h and file2.h
  file2.cc: only includes file1.h
  file2.h: Has a forward declaration of the class


----------------      -----------------
| file1.h       |     | file2.h        |
| class Simple{ |     | class Simple;  |
|    ...        |     |                |
| }             |     |                |
-----------------     ------------------

--------------------
| file2.cc         |
| #include file1.h |
--------------------

-------------------------
| file1.cc              |
| #include file1.h      |
| #include file2.h      |
|                       |
| [*] Simple::Simple() { }
------------------------
[*] error HERE


If I pass file2.cc and file1.cc to the indexer I get these problems:
[with CPPSemantics.traceBindingResolution turned on]

Resolving Simple:105
  Resolving Simple:97
  Resolved  Simple:97 to Simple CPPClassType:9690924
Indexer: unresolved name at /usr/local/clients/repro/file1.cc(5); A scope could not be created to represent the name Simple
  Resolving z:132
Indexer: unresolved name at /usr/local/clients/repro/file1.cc(5); A scope could not be created to represent the name z


If I pass file1.cc before file2.cc, everything works fine.
If I use the "full" indexer everything works fine.

Real Sample files:
::::::::::::::
file1.cc
::::::::::::::

#include "file1.h"
#include "file2.h"

Simple::Simple(const char* fname) :z(1) {

};
::::::::::::::
file2.cc
::::::::::::::
#include "file1.h"
::::::::::::::
file1.h
::::::::::::::
#ifndef _FILE1_H
#define _FILE1_H

class Simple {
 public:
  Simple(const char* fname);
  int z;
};

#endif
::::::::::::::
file2.h
::::::::::::::
#ifndef _FILE2_H
#define _FILE2_H

class Simple;

#endif



=========================================
I couldn't find any sample code that runs the standalone indexer so here is
my attempt.

To compile/run:
   javac -cp "all_jars_from_eclipse_plugin_dir" MyStandaloneIndexer.java
   java -cp "all_jars_from_eclipse_plugin_dir" MyStandaloneIndexer file2.cc file1.cc

NOTE: that the include path is setup to find file2.h and file1.h in the directory you
run java from or in /tmp.

============

import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.core.index.URIRelativeLocationConverter;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.indexer.ILanguageMapper;
import org.eclipse.cdt.internal.core.indexer.IStandaloneScannerInfoProvider;
import org.eclipse.cdt.internal.core.indexer.StandaloneFastIndexer;
import org.eclipse.cdt.internal.core.indexer.StdoutLogService;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory;
import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCLinkageFactory;
import org.eclipse.cdt.internal.core.pdom.dom.cpp.PDOMCPPLinkageFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author rbraunstein@xxxxxxxxxx (Ronald Braunstein)
 */
public class MyStandaloneIndexer extends StandaloneFastIndexer {

  // Used by the cdt to help figure out which internal parsers to use for C, c++ and fortran.
  static HashMap<String, IPDOMLinkageFactory> linkageFactoryMappings =
      new HashMap<String, IPDOMLinkageFactory>();
  static {
    linkageFactoryMappings.put(ILinkage.CPP_LINKAGE_NAME, new PDOMCPPLinkageFactory());
  }

  public static void main(String args[]) throws Exception {
    File writableIndex = new File("/tmp/standaloneIndexFile.pdom");
    MyStandaloneIndexer indexer = new MyStandaloneIndexer(writableIndex);
    indexer.setTraceStatistics(true);
    ArrayList<String> files = new ArrayList();
    for (String arg : args) {
      files.add(arg);
    }
    indexer.rebuild(files, new MyProgressMonitor());
  }

  public MyStandaloneIndexer(File writableIndexFile) throws Exception {
    super(
        writableIndexFile,
        new URIRelativeLocationConverter(new URI("file", "/", null)),
        linkageFactoryMappings,
        new MyScannerProvider(),
        new MyLanguageMapper(),
        new StdoutLogService());
    setShowActivity(true);
    setShowProblems(true);
  }

  static public class MyLanguageMapper implements ILanguageMapper {
    public ILanguage getLanguage(String file) {
      return GPPLanguage.getDefault();
    }
  }

 static public class MyScannerProvider implements IStandaloneScannerInfoProvider {
   MyScannerInfo myInfo = new MyScannerInfo();
   public IScannerInfo getScannerInformation(String path) {
     return myInfo;
    }
    public IScannerInfo getDefaultScannerInformation(int linkageID) {
      return myInfo;
    }
  }

  // NOTE: sets include path to /tmp followed by the current dir.
  static public class MyScannerInfo implements IScannerInfo {
    final String[] includePath = new String[] {
      "/tmp",
      System.getProperty("user.dir")
    };
    final Map<String, String> defines = new HashMap<String, String>();
    public Map<String, String> getDefinedSymbols() {
      return defines;
    };
    public String[] getIncludePaths() {
      return includePath;
    };
  }

  // Use NullProgressMonitor if we don't care.
  static public class MyProgressMonitor implements IProgressMonitor {
    public void beginTask(String name, int totalWork) {
      System.out.println("monitor: Beginning task: " + name);
    }
    public void done() {  System.out.println("monitor: DONE"); }
    public void internalWorked(double work) { System.out.println("monitor: internalWorked: " + work); }
    public boolean isCanceled() { return false; }
    public void setCanceled(boolean value) { System.out.println("monitor: setCanceled: " + value); }
    public void setTaskName(String name) { System.out.println("monitor: setTaskName: " + name); }
    public void subTask(String name) { System.out.println("monitor: subtask: " + name); }
    public void worked(int work) { System.out.println("monitor: worked: " + work); }
  }
}