forked from qt-creator/qt-creator
Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline
This commit is contained in:
@@ -37,6 +37,8 @@
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QEventLoop>
|
||||
#include <QtCore/QTextCodec>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDir>
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
|
||||
@@ -366,5 +368,108 @@ void SynchronousProcess::processStdErr(bool emitSignals)
|
||||
}
|
||||
}
|
||||
|
||||
// Path utilities
|
||||
|
||||
enum OS_Type { OS_Mac, OS_Windows, OS_Unix };
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
static const OS_Type pathOS = OS_Windows;
|
||||
#else
|
||||
# ifdef Q_OS_MAC
|
||||
static const OS_Type pathOS = OS_Mac;
|
||||
# else
|
||||
static const OS_Type pathOS = OS_Unix;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Locate a binary in a directory, applying all kinds of
|
||||
// extensions the operating system supports.
|
||||
static QString checkBinary(const QDir &dir, const QString &binary)
|
||||
{
|
||||
// naive UNIX approach
|
||||
const QFileInfo info(dir.filePath(binary));
|
||||
if (info.isFile() && info.isExecutable())
|
||||
return info.absoluteFilePath();
|
||||
|
||||
// Does the OS have some weird extension concept or does the
|
||||
// binary have a 3 letter extension?
|
||||
if (pathOS == OS_Unix)
|
||||
return QString();
|
||||
const int dotIndex = binary.lastIndexOf(QLatin1Char('.'));
|
||||
if (dotIndex != -1 && dotIndex == binary.size() - 4)
|
||||
return QString();
|
||||
|
||||
switch (pathOS) {
|
||||
case OS_Unix:
|
||||
break;
|
||||
case OS_Windows: {
|
||||
static const char *windowsExtensions[] = {".cmd", ".bat", ".exe", ".com" };
|
||||
// Check the Windows extensions using the order
|
||||
const int windowsExtensionCount = sizeof(windowsExtensions)/sizeof(const char*);
|
||||
for (int e = 0; e < windowsExtensionCount; e ++) {
|
||||
const QFileInfo windowsBinary(dir.filePath(binary + QLatin1String(windowsExtensions[e])));
|
||||
if (windowsBinary.isFile() && windowsBinary.isExecutable())
|
||||
return windowsBinary.absoluteFilePath();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OS_Mac: {
|
||||
// Check for Mac app folders
|
||||
const QFileInfo appFolder(dir.filePath(binary + QLatin1String(".app")));
|
||||
if (appFolder.isDir()) {
|
||||
QString macBinaryPath = appFolder.absoluteFilePath();
|
||||
macBinaryPath += QLatin1String("/Contents/MacOS/");
|
||||
macBinaryPath += binary;
|
||||
const QFileInfo macBinary(macBinaryPath);
|
||||
if (macBinary.isFile() && macBinary.isExecutable())
|
||||
return macBinary.absoluteFilePath();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString SynchronousProcess::locateBinary(const QString &path, const QString &binary)
|
||||
{
|
||||
// Absolute file?
|
||||
const QFileInfo absInfo(binary);
|
||||
if (absInfo.isAbsolute())
|
||||
return checkBinary(absInfo.dir(), absInfo.fileName());
|
||||
|
||||
// Windows finds binaries in the current directory
|
||||
if (pathOS == OS_Windows) {
|
||||
const QString currentDirBinary = checkBinary(QDir::current(), binary);
|
||||
if (!currentDirBinary.isEmpty())
|
||||
return currentDirBinary;
|
||||
}
|
||||
|
||||
const QStringList paths = path.split(pathSeparator());
|
||||
if (paths.empty())
|
||||
return QString();
|
||||
const QStringList::const_iterator cend = paths.constEnd();
|
||||
for (QStringList::const_iterator it = paths.constBegin(); it != cend; ++it) {
|
||||
const QDir dir(*it);
|
||||
const QString rc = checkBinary(dir, binary);
|
||||
if (!rc.isEmpty())
|
||||
return rc;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString SynchronousProcess::locateBinary(const QString &binary)
|
||||
{
|
||||
const QByteArray path = qgetenv("PATH");
|
||||
return locateBinary(QString::fromLocal8Bit(path), binary);
|
||||
}
|
||||
|
||||
QChar SynchronousProcess::pathSeparator()
|
||||
{
|
||||
if (pathOS == OS_Windows)
|
||||
return QLatin1Char(';');
|
||||
return QLatin1Char(':');
|
||||
}
|
||||
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace Core
|
||||
|
@@ -114,6 +114,12 @@ public:
|
||||
|
||||
SynchronousProcessResponse run(const QString &binary, const QStringList &args);
|
||||
|
||||
// Helpers to find binaries. Do not use it for other path variables
|
||||
// and file types.
|
||||
static QString locateBinary(const QString &binary);
|
||||
static QString locateBinary(const QString &path, const QString &binary);
|
||||
static QChar pathSeparator();
|
||||
|
||||
signals:
|
||||
void stdOut(const QByteArray &data, bool firstTime);
|
||||
void stdErr(const QByteArray &data, bool firstTime);
|
||||
|
@@ -102,8 +102,10 @@ GitClient::GitClient(GitPlugin* plugin)
|
||||
m_plugin(plugin),
|
||||
m_core(Core::ICore::instance())
|
||||
{
|
||||
if (QSettings *s = m_core->settings())
|
||||
if (QSettings *s = m_core->settings()) {
|
||||
m_settings.fromSettings(s);
|
||||
m_binaryPath = m_settings.gitBinaryPath();
|
||||
}
|
||||
}
|
||||
|
||||
GitClient::~GitClient()
|
||||
@@ -478,7 +480,7 @@ GitCommand *GitClient::createCommand(const QString &workingDirectory,
|
||||
if (m_settings.adoptPath)
|
||||
environment.set(QLatin1String("PATH"), m_settings.path);
|
||||
|
||||
GitCommand* command = new GitCommand(workingDirectory, environment);
|
||||
GitCommand* command = new GitCommand(m_binaryPath, workingDirectory, environment);
|
||||
if (outputToWindow) {
|
||||
if (!editor) { // assume that the commands output is the important thing
|
||||
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(appendDataAndPopup(QByteArray)));
|
||||
@@ -527,10 +529,9 @@ bool GitClient::synchronousGit(const QString &workingDirectory,
|
||||
{
|
||||
if (Git::Constants::debug)
|
||||
qDebug() << "synchronousGit" << workingDirectory << arguments;
|
||||
const QString binary = QLatin1String(Constants::GIT_BINARY);
|
||||
|
||||
if (logCommandToWindow)
|
||||
m_plugin->outputWindow()->append(formatCommand(binary, arguments));
|
||||
m_plugin->outputWindow()->append(formatCommand(m_binaryPath, arguments));
|
||||
|
||||
QProcess process;
|
||||
process.setWorkingDirectory(workingDirectory);
|
||||
@@ -540,7 +541,7 @@ bool GitClient::synchronousGit(const QString &workingDirectory,
|
||||
environment.set(QLatin1String("PATH"), m_settings.path);
|
||||
process.setEnvironment(environment.toStringList());
|
||||
|
||||
process.start(binary, arguments);
|
||||
process.start(m_binaryPath, arguments);
|
||||
if (!process.waitForFinished()) {
|
||||
if (errorText)
|
||||
*errorText = "Error: Git timed out";
|
||||
@@ -1000,6 +1001,6 @@ void GitClient::setSettings(const GitSettings &s)
|
||||
m_settings = s;
|
||||
if (QSettings *s = m_core->settings())
|
||||
m_settings.toSettings(s);
|
||||
m_binaryPath = m_settings.gitBinaryPath();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -176,6 +176,7 @@ private:
|
||||
GitPlugin *m_plugin;
|
||||
Core::ICore *m_core;
|
||||
GitSettings m_settings;
|
||||
QString m_binaryPath;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -61,8 +61,10 @@ GitCommand::Job::Job(const QStringList &a, int t) :
|
||||
{
|
||||
}
|
||||
|
||||
GitCommand::GitCommand(const QString &workingDirectory,
|
||||
GitCommand::GitCommand(const QString &binaryPath,
|
||||
const QString &workingDirectory,
|
||||
ProjectExplorer::Environment &environment) :
|
||||
m_binaryPath(binaryPath),
|
||||
m_workingDirectory(workingDirectory),
|
||||
m_environment(environmentToList(environment))
|
||||
{
|
||||
@@ -109,7 +111,7 @@ void GitCommand::run()
|
||||
if (Git::Constants::debug)
|
||||
qDebug() << "GitCommand::run" << j << '/' << count << m_jobs.at(j).arguments;
|
||||
|
||||
process.start(QLatin1String(Constants::GIT_BINARY), m_jobs.at(j).arguments);
|
||||
process.start(m_binaryPath, m_jobs.at(j).arguments);
|
||||
if (!process.waitForFinished(m_jobs.at(j).timeout * 1000)) {
|
||||
ok = false;
|
||||
error += QLatin1String("Error: Git timed out");
|
||||
|
@@ -43,9 +43,11 @@ namespace Internal {
|
||||
|
||||
class GitCommand : public QObject
|
||||
{
|
||||
Q_DISABLE_COPY(GitCommand)
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GitCommand(const QString &workingDirectory,
|
||||
explicit GitCommand(const QString &binaryPath,
|
||||
const QString &workingDirectory,
|
||||
ProjectExplorer::Environment &environment);
|
||||
|
||||
|
||||
@@ -67,8 +69,7 @@ private:
|
||||
int timeout;
|
||||
};
|
||||
|
||||
QStringList environment() const;
|
||||
|
||||
const QString m_binaryPath;
|
||||
const QString m_workingDirectory;
|
||||
const QStringList m_environment;
|
||||
|
||||
|
@@ -32,9 +32,13 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "gitsettings.h"
|
||||
#include "gitconstants.h"
|
||||
|
||||
#include <utils/synchronousprocess.h>
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
static const char *groupC = "Git";
|
||||
static const char *sysEnvKeyC = "SysEnv";
|
||||
@@ -79,5 +83,30 @@ bool GitSettings::equals(const GitSettings &s) const
|
||||
return adoptPath == s.adoptPath && path == s.path && logCount == s.logCount && timeout == s.timeout;
|
||||
}
|
||||
|
||||
QString GitSettings::gitBinaryPath(bool *ok, QString *errorMessage) const
|
||||
{
|
||||
// Locate binary in path if one is specified, otherwise default
|
||||
// to pathless binary
|
||||
if (ok)
|
||||
*ok = true;
|
||||
if (errorMessage)
|
||||
errorMessage->clear();
|
||||
const QString binary = QLatin1String(Constants::GIT_BINARY);
|
||||
// Easy, git is assumed to be elsewhere accessible
|
||||
if (!adoptPath)
|
||||
return binary;
|
||||
// Search in path?
|
||||
const QString pathBinary = Core::Utils::SynchronousProcess::locateBinary(path, binary);
|
||||
if (pathBinary.isEmpty()) {
|
||||
if (ok)
|
||||
*ok = false;
|
||||
if (errorMessage)
|
||||
*errorMessage = QCoreApplication::translate("GitSettings",
|
||||
"The binary '%1' could not be located in the path '%2'").arg(binary, path);
|
||||
return binary;
|
||||
}
|
||||
return pathBinary;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -51,6 +51,8 @@ struct GitSettings
|
||||
void fromSettings(QSettings *);
|
||||
void toSettings(QSettings *) const;
|
||||
|
||||
QString gitBinaryPath(bool *ok = 0, QString *errorMessage = 0) const;
|
||||
|
||||
bool equals(const GitSettings &s) const;
|
||||
|
||||
bool adoptPath;
|
||||
|
@@ -36,8 +36,10 @@
|
||||
#include "gitplugin.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtGui/QMessageBox>
|
||||
|
||||
using namespace Git::Internal;
|
||||
namespace Git {
|
||||
namespace Internal {
|
||||
|
||||
SettingsPageWidget::SettingsPageWidget(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
@@ -101,6 +103,17 @@ void SettingsPage::apply()
|
||||
{
|
||||
if (!m_widget)
|
||||
return;
|
||||
const GitSettings newSettings = m_widget->settings();
|
||||
// Warn if git cannot be found in path if the widget is on top
|
||||
if (m_widget->isVisible()) {
|
||||
bool gitFoundOk;
|
||||
QString errorMessage;
|
||||
newSettings.gitBinaryPath(&gitFoundOk, &errorMessage);
|
||||
if (!gitFoundOk)
|
||||
QMessageBox::warning(m_widget, tr("Git Settings"), errorMessage);
|
||||
}
|
||||
|
||||
GitPlugin::instance()->setSettings(m_widget->settings());
|
||||
GitPlugin::instance()->setSettings(newSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -77,12 +77,7 @@ int ASTVisitor::tokenKind(unsigned index) const
|
||||
{ return translationUnit()->tokenKind(index); }
|
||||
|
||||
const char *ASTVisitor::spell(unsigned index) const
|
||||
{
|
||||
if (! index)
|
||||
return 0;
|
||||
|
||||
return translationUnit()->tokenAt(index).spell();
|
||||
}
|
||||
{ return translationUnit()->spell(index); }
|
||||
|
||||
Identifier *ASTVisitor::identifier(unsigned index) const
|
||||
{ return translationUnit()->identifier(index); }
|
||||
|
@@ -389,6 +389,11 @@ bool CheckDeclaration::visit(UsingDirectiveAST *ast)
|
||||
UsingNamespaceDirective *u = control()->newUsingNamespaceDirective(ast->firstToken(), name);
|
||||
ast->symbol = u;
|
||||
_scope->enterSymbol(u);
|
||||
|
||||
if (! (_scope->isBlockScope() || _scope->isNamespaceScope()))
|
||||
translationUnit()->error(ast->firstToken(),
|
||||
"using-directive not within namespace or block scope");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -134,6 +134,14 @@ const Token &TranslationUnit::tokenAt(unsigned index) const
|
||||
int TranslationUnit::tokenKind(unsigned index) const
|
||||
{ return _tokens->at(index).kind; }
|
||||
|
||||
const char *TranslationUnit::spell(unsigned index) const
|
||||
{
|
||||
if (! index)
|
||||
return 0;
|
||||
|
||||
return _tokens->at(index).spell();
|
||||
}
|
||||
|
||||
Identifier *TranslationUnit::identifier(unsigned index) const
|
||||
{ return _tokens->at(index).identifier; }
|
||||
|
||||
|
@@ -87,6 +87,7 @@ public:
|
||||
unsigned tokenCount() const;
|
||||
const Token &tokenAt(unsigned index) const;
|
||||
int tokenKind(unsigned index) const;
|
||||
const char *spell(unsigned index) const;
|
||||
|
||||
unsigned matchingBrace(unsigned index) const;
|
||||
Identifier *identifier(unsigned index) const;
|
||||
|
@@ -43,6 +43,8 @@
|
||||
#include <Symbols.h>
|
||||
#include <Literals.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
@@ -55,6 +57,40 @@
|
||||
// NamespaceBinding
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Location
|
||||
{
|
||||
public:
|
||||
Location()
|
||||
: _fileId(0),
|
||||
_sourceLocation(0)
|
||||
{ }
|
||||
|
||||
Location(Symbol *symbol)
|
||||
: _fileId(symbol->fileId()),
|
||||
_sourceLocation(symbol->sourceLocation())
|
||||
{ }
|
||||
|
||||
Location(StringLiteral *fileId, unsigned sourceLocation)
|
||||
: _fileId(fileId), _sourceLocation(sourceLocation)
|
||||
{ }
|
||||
|
||||
inline bool isValid() const
|
||||
{ return _fileId != 0; }
|
||||
|
||||
inline operator bool() const
|
||||
{ return _fileId != 0; }
|
||||
|
||||
inline StringLiteral *fileId() const
|
||||
{ return _fileId; }
|
||||
|
||||
inline unsigned sourceLocation() const
|
||||
{ return _sourceLocation; }
|
||||
|
||||
private:
|
||||
StringLiteral *_fileId;
|
||||
unsigned _sourceLocation;
|
||||
};
|
||||
|
||||
class NamespaceBinding
|
||||
{
|
||||
public:
|
||||
@@ -79,6 +115,10 @@ public:
|
||||
/// Returns the binding associated with the given symbol.
|
||||
NamespaceBinding *findOrCreateNamespaceBinding(Namespace *symbol);
|
||||
|
||||
NamespaceBinding *resolveNamespace(const Location &loc,
|
||||
Name *name,
|
||||
bool lookAtParent = true);
|
||||
|
||||
/// Helpers.
|
||||
std::string qualifiedId() const;
|
||||
void dump();
|
||||
@@ -96,6 +136,9 @@ public: // attributes
|
||||
/// This binding's connections.
|
||||
Array<NamespaceBinding *> children;
|
||||
|
||||
/// This binding's list of using namespaces.
|
||||
Array<NamespaceBinding *> usings;
|
||||
|
||||
/// This binding's namespace symbols.
|
||||
Array<Namespace *> symbols;
|
||||
};
|
||||
@@ -211,6 +254,104 @@ NamespaceBinding *NamespaceBinding::findOrCreateNamespaceBinding(Namespace *symb
|
||||
return binding;
|
||||
}
|
||||
|
||||
static void closure(const Location &loc,
|
||||
NamespaceBinding *binding, Name *name,
|
||||
Array<NamespaceBinding *> *bindings)
|
||||
{
|
||||
for (unsigned i = 0; i < bindings->size(); ++i) {
|
||||
NamespaceBinding *b = bindings->at(i);
|
||||
|
||||
if (b == binding)
|
||||
return;
|
||||
}
|
||||
|
||||
bindings->push_back(binding);
|
||||
|
||||
assert(name->isNameId());
|
||||
|
||||
Identifier *id = name->asNameId()->identifier();
|
||||
bool ignoreUsingDirectives = false;
|
||||
|
||||
for (unsigned i = 0; i < binding->symbols.size(); ++i) {
|
||||
Namespace *symbol = binding->symbols.at(i);
|
||||
Scope *scope = symbol->members();
|
||||
|
||||
for (Symbol *symbol = scope->lookat(id); symbol; symbol = symbol->next()) {
|
||||
if (symbol->name() != name || ! symbol->isNamespace())
|
||||
continue;
|
||||
|
||||
const Location l(symbol);
|
||||
|
||||
if (l.fileId() == loc.fileId() && l.sourceLocation() < loc.sourceLocation()) {
|
||||
ignoreUsingDirectives = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoreUsingDirectives)
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < binding->usings.size(); ++i) {
|
||||
NamespaceBinding *u = binding->usings.at(i);
|
||||
|
||||
closure(loc, u, name, bindings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NamespaceBinding *NamespaceBinding::resolveNamespace(const Location &loc,
|
||||
Name *name,
|
||||
bool lookAtParent)
|
||||
{
|
||||
if (! name)
|
||||
return 0;
|
||||
|
||||
else if (NameId *nameId = name->asNameId()) {
|
||||
Array<NamespaceBinding *> bindings;
|
||||
closure(loc, this, nameId, &bindings);
|
||||
|
||||
Array<NamespaceBinding *> results;
|
||||
|
||||
for (unsigned i = 0; i < bindings.size(); ++i) {
|
||||
NamespaceBinding *binding = bindings.at(i);
|
||||
|
||||
if (NamespaceBinding *b = binding->findNamespaceBinding(nameId))
|
||||
results.push_back(b);
|
||||
}
|
||||
|
||||
if (results.size() == 1)
|
||||
return results.at(0);
|
||||
|
||||
else if (results.size() > 1) {
|
||||
// ### FIXME: return 0;
|
||||
return results.at(0);
|
||||
}
|
||||
|
||||
else if (parent && lookAtParent)
|
||||
return parent->resolveNamespace(loc, name);
|
||||
|
||||
} else if (QualifiedNameId *q = name->asQualifiedNameId()) {
|
||||
if (q->nameCount() == 1) {
|
||||
assert(q->isGlobal());
|
||||
|
||||
return globalNamespaceBinding()->resolveNamespace(loc, q->nameAt(0));
|
||||
}
|
||||
|
||||
NamespaceBinding *current = this;
|
||||
if (q->isGlobal())
|
||||
current = globalNamespaceBinding();
|
||||
|
||||
current = current->resolveNamespace(loc, q->nameAt(0));
|
||||
for (unsigned i = 1; current && i < q->nameCount(); ++i)
|
||||
current = current->resolveNamespace(loc, q->nameAt(i), false);
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ### rewrite me
|
||||
std::string NamespaceBinding::qualifiedId() const
|
||||
{
|
||||
@@ -255,28 +396,38 @@ public:
|
||||
Binder();
|
||||
virtual ~Binder();
|
||||
|
||||
NamespaceBinding *operator()(Symbol *symbol)
|
||||
{ return bind(symbol, 0); }
|
||||
NamespaceBinding *operator()(TranslationUnit *u, Namespace *globals)
|
||||
{
|
||||
TranslationUnit *previousUnit = unit;
|
||||
unit = u;
|
||||
NamespaceBinding *binding = bind(globals, 0);
|
||||
unit = previousUnit;
|
||||
return binding;
|
||||
}
|
||||
|
||||
protected:
|
||||
NamespaceBinding *bind(Symbol *symbol, NamespaceBinding *binding);
|
||||
NamespaceBinding *findOrCreateNamespaceBinding(Namespace *symbol);
|
||||
NamespaceBinding *resolveNamespace(const Location &loc, Name *name);
|
||||
|
||||
NamespaceBinding *switchNamespaceBinding(NamespaceBinding *binding);
|
||||
|
||||
using SymbolVisitor::visit;
|
||||
|
||||
virtual bool visit(Namespace *);
|
||||
virtual bool visit(UsingNamespaceDirective *);
|
||||
virtual bool visit(Class *);
|
||||
virtual bool visit(Function *);
|
||||
virtual bool visit(Block *);
|
||||
|
||||
private:
|
||||
NamespaceBinding *namespaceBinding;
|
||||
TranslationUnit *unit;
|
||||
};
|
||||
|
||||
Binder::Binder()
|
||||
: namespaceBinding(0)
|
||||
: namespaceBinding(0),
|
||||
unit(0)
|
||||
{ }
|
||||
|
||||
Binder::~Binder()
|
||||
@@ -299,6 +450,15 @@ NamespaceBinding *Binder::findOrCreateNamespaceBinding(Namespace *symbol)
|
||||
return namespaceBinding;
|
||||
}
|
||||
|
||||
NamespaceBinding *Binder::resolveNamespace(const Location &loc, Name *name)
|
||||
{
|
||||
if (! namespaceBinding)
|
||||
return 0;
|
||||
|
||||
return namespaceBinding->resolveNamespace(loc, name);
|
||||
}
|
||||
|
||||
|
||||
NamespaceBinding *Binder::switchNamespaceBinding(NamespaceBinding *binding)
|
||||
{
|
||||
NamespaceBinding *previousBinding = namespaceBinding;
|
||||
@@ -319,6 +479,20 @@ bool Binder::visit(Namespace *symbol)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Binder::visit(UsingNamespaceDirective *u)
|
||||
{
|
||||
NamespaceBinding *resolved = resolveNamespace(Location(u), u->name());
|
||||
|
||||
if (! resolved) {
|
||||
unit->error(u->sourceLocation(), "expected namespace-name");
|
||||
return false;
|
||||
}
|
||||
|
||||
namespaceBinding->usings.push_back(resolved);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Binder::visit(Class *)
|
||||
{ return false; }
|
||||
|
||||
@@ -376,7 +550,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
// bind
|
||||
Binder bind;
|
||||
NamespaceBinding *binding = bind(globalNamespace);
|
||||
NamespaceBinding *binding = bind(&unit, globalNamespace);
|
||||
binding->dump();
|
||||
delete binding;
|
||||
|
||||
|
Reference in New Issue
Block a user