Commit 43bf95a1 authored by hjk's avatar hjk
Browse files

Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

parents 6049e1fb c6004485
......@@ -2,8 +2,8 @@
## Open script-dir-homed subshell
(
ABS_SCRIPT_DIR=`pwd`/`dirname "$0"`
cd "${ABS_SCRIPT_DIR}"
ABS_SCRIPT_DIR=$(cd $(dirname $(which "$0")) && pwd)
cd "${ABS_SCRIPT_DIR}" || exit 1
## Internal config
......
......@@ -530,11 +530,15 @@ bool ProFileEvaluator::Private::visitBeginProBlock(ProBlock *block)
if (!m_skipLevel) {
m_prevCondition = m_condition;
m_condition = ConditionFalse;
} else {
Q_ASSERT(m_condition != ConditionTrue);
}
} else if (block->blockKind() & ProBlock::ScopeContentsKind) {
m_updateCondition = false;
if (m_condition != ConditionTrue)
++m_skipLevel;
else
Q_ASSERT(!m_skipLevel);
}
return true;
}
......@@ -542,8 +546,14 @@ bool ProFileEvaluator::Private::visitBeginProBlock(ProBlock *block)
bool ProFileEvaluator::Private::visitEndProBlock(ProBlock *block)
{
if (block->blockKind() & ProBlock::ScopeContentsKind) {
if (m_skipLevel)
if (m_skipLevel) {
Q_ASSERT(m_condition != ConditionTrue);
--m_skipLevel;
} else {
// Conditionals contained inside this block may have changed the state.
// So we reset it here to make an else following us do the right thing.
m_condition = ConditionTrue;
}
}
return true;
}
......@@ -572,8 +582,12 @@ bool ProFileEvaluator::Private::visitProCondition(ProCondition *cond)
{
if (!m_skipLevel) {
if (cond->text().toLower() == QLatin1String("else")) {
// The state ConditionElse makes sure that subsequential elses are ignored.
// That's braindead, but qmake is like that.
if (m_prevCondition == ConditionTrue)
m_condition = ConditionElse;
else if (m_prevCondition == ConditionFalse)
m_condition = ConditionTrue;
} else if (m_condition == ConditionFalse) {
if (isActiveConfig(cond->text(), true) ^ m_invertNext)
m_condition = ConditionTrue;
......@@ -807,7 +821,7 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value)
bool ProFileEvaluator::Private::visitProFunction(ProFunction *func)
{
if (!m_skipLevel && (!m_updateCondition || m_condition == ConditionFalse)) {
if (!m_updateCondition || m_condition == ConditionFalse) {
QString text = func->text();
int lparen = text.indexOf(QLatin1Char('('));
int rparen = text.lastIndexOf(QLatin1Char(')'));
......@@ -815,10 +829,12 @@ bool ProFileEvaluator::Private::visitProFunction(ProFunction *func)
QString arguments = text.mid(lparen + 1, rparen - lparen - 1);
QString funcName = text.left(lparen);
m_lineNo = func->lineNumber();
bool result = false;
if (!evaluateConditionalFunction(funcName.trimmed(), arguments, &result))
bool result;
if (!evaluateConditionalFunction(funcName.trimmed(), arguments, &result)) {
m_invertNext = false;
return false;
if (result ^ m_invertNext)
}
if (!m_skipLevel && (result ^ m_invertNext))
m_condition = ConditionTrue;
}
m_invertNext = false;
......@@ -1556,7 +1572,7 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
}
break;
case 0:
q->logMessage(format("'%1' is not a function").arg(func));
q->logMessage(format("'%1' is not a recognized replace function").arg(func));
break;
default:
q->logMessage(format("Function '%1' is not implemented").arg(func));
......@@ -1577,26 +1593,67 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
for (int i = 0; i < argumentsList.count(); ++i)
args += expandVariableReferences(argumentsList[i]).join(sep);
enum ConditionFunc { CF_CONFIG = 1, CF_CONTAINS, CF_COUNT, CF_EXISTS, CF_INCLUDE,
CF_LOAD, CF_ISEMPTY, CF_SYSTEM, CF_MESSAGE};
enum TestFunc { T_REQUIRES=1, T_GREATERTHAN, T_LESSTHAN, T_EQUALS,
T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
T_RETURN, T_BREAK, T_NEXT, T_DEFINED, T_CONTAINS, T_INFILE,
T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_MESSAGE, T_IF };
static QHash<QString, int> *functions = 0;
if (!functions) {
functions = new QHash<QString, int>;
functions->insert(QLatin1String("load"), CF_LOAD); //v
functions->insert(QLatin1String("include"), CF_INCLUDE); //v
functions->insert(QLatin1String("message"), CF_MESSAGE); //v
functions->insert(QLatin1String("warning"), CF_MESSAGE); //v
functions->insert(QLatin1String("error"), CF_MESSAGE); //v
functions->insert(QLatin1String("requires"), T_REQUIRES);
functions->insert(QLatin1String("greaterThan"), T_GREATERTHAN);
functions->insert(QLatin1String("lessThan"), T_LESSTHAN);
functions->insert(QLatin1String("equals"), T_EQUALS);
functions->insert(QLatin1String("isEqual"), T_EQUALS);
functions->insert(QLatin1String("exists"), T_EXISTS);
functions->insert(QLatin1String("export"), T_EXPORT);
functions->insert(QLatin1String("clear"), T_CLEAR);
functions->insert(QLatin1String("unset"), T_UNSET);
functions->insert(QLatin1String("eval"), T_EVAL);
functions->insert(QLatin1String("CONFIG"), T_CONFIG);
functions->insert(QLatin1String("if"), T_IF);
functions->insert(QLatin1String("isActiveConfig"), T_CONFIG);
functions->insert(QLatin1String("system"), T_SYSTEM);
functions->insert(QLatin1String("return"), T_RETURN);
functions->insert(QLatin1String("break"), T_BREAK);
functions->insert(QLatin1String("next"), T_NEXT);
functions->insert(QLatin1String("defined"), T_DEFINED);
functions->insert(QLatin1String("contains"), T_CONTAINS);
functions->insert(QLatin1String("infile"), T_INFILE);
functions->insert(QLatin1String("count"), T_COUNT);
functions->insert(QLatin1String("isEmpty"), T_ISEMPTY);
functions->insert(QLatin1String("load"), T_LOAD); //v
functions->insert(QLatin1String("include"), T_INCLUDE); //v
functions->insert(QLatin1String("debug"), T_DEBUG);
functions->insert(QLatin1String("message"), T_MESSAGE); //v
functions->insert(QLatin1String("warning"), T_MESSAGE); //v
functions->insert(QLatin1String("error"), T_MESSAGE); //v
}
bool cond = false;
bool ok = true;
ConditionFunc func_t = (ConditionFunc)functions->value(function);
TestFunc func_t = (TestFunc)functions->value(function);
switch (func_t) {
case CF_CONFIG: {
#if 0
case T_INFILE:
case T_REQUIRES:
case T_GREATERTHAN:
case T_LESSTHAN:
case T_EQUALS:
case T_EXPORT:
case T_CLEAR:
case T_UNSET:
case T_EVAL:
case T_IF:
case T_RETURN:
case T_BREAK:
case T_NEXT:
case T_DEFINED:
#endif
case T_CONFIG: {
if (args.count() < 1 || args.count() > 2) {
q->logMessage(format("CONFIG(config) requires one or two arguments."));
ok = false;
......@@ -1618,7 +1675,7 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
}
break;
}
case CF_CONTAINS: {
case T_CONTAINS: {
if (args.count() < 2 || args.count() > 3) {
q->logMessage(format("contains(var, val) requires two or three arguments."));
ok = false;
......@@ -1650,9 +1707,9 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
break;
}
case CF_COUNT: {
case T_COUNT: {
if (args.count() != 2 && args.count() != 3) {
q->logMessage(format("count(var, count) requires two or three arguments."));
q->logMessage(format("count(var, count, op=\"equals\") requires two or three arguments."));
ok = false;
break;
}
......@@ -1677,7 +1734,9 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
cond = values(args.first()).count() == args[1].toInt();
break;
}
case CF_INCLUDE: {
case T_INCLUDE: {
if (m_skipLevel && !m_cumulative)
break;
QString parseInto;
if (args.count() == 2) {
parseInto = args[1];
......@@ -1693,7 +1752,9 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
ok = evaluateFile(fileName, &ok);
break;
}
case CF_LOAD: {
case T_LOAD: {
if (m_skipLevel && !m_cumulative)
break;
QString parseInto;
bool ignore_error = false;
if (args.count() == 2) {
......@@ -1707,13 +1768,16 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
ok = evaluateFeatureFile( args.first(), &cond);
break;
}
case CF_MESSAGE: {
case T_DEBUG:
// Yup - do nothing. Nothing is going to enable debug output anyway.
break;
case T_MESSAGE: {
if (args.count() != 1) {
q->logMessage(format("%1(message) requires one argument.").arg(function));
ok = false;
break;
}
QString msg = args.first();
QString msg = fixEnvVariables(args.first());
if (function == QLatin1String("error")) {
QStringList parents;
foreach (ProFile *proFile, m_profileStack)
......@@ -1730,7 +1794,8 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
}
break;
}
case CF_SYSTEM: {
#if 0 // Way too dangerous to enable.
case T_SYSTEM: {
if (args.count() != 1) {
q->logMessage(format("system(exec) requires one argument."));
ok = false;
......@@ -1739,7 +1804,8 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
ok = system(args.first().toLatin1().constData()) == 0;
break;
}
case CF_ISEMPTY: {
#endif
case T_ISEMPTY: {
if (args.count() != 1) {
q->logMessage(format("isEmpty(var) requires one argument."));
ok = false;
......@@ -1754,7 +1820,7 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
}
break;
}
case CF_EXISTS: {
case T_EXISTS: {
if (args.count() != 1) {
q->logMessage(format("exists(file) requires one argument."));
ok = false;
......@@ -1778,6 +1844,13 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
break;
}
case 0:
// This is too chatty currently (missing defineTest and defineReplace)
//q->logMessage(format("'%1' is not a recognized test function").arg(function));
break;
default:
q->logMessage(format("Function '%1' is not implemented").arg(function));
break;
}
if (result)
......@@ -1975,7 +2048,13 @@ bool ProFileEvaluator::Private::evaluateFeatureFile(const QString &fileName, boo
break;
}
}
return fn.isEmpty() ? false : evaluateFile(fn, result);
if (fn.isEmpty())
return false;
bool cumulative = m_cumulative;
m_cumulative = false;
bool ok = evaluateFile(fn, result);
m_cumulative = cumulative;
return ok;
}
void ProFileEvaluator::Private::expandPatternHelper(const QString &relName, const QString &absName,
......@@ -2085,14 +2164,23 @@ bool ProFileEvaluator::contains(const QString &variableName) const
return d->m_valuemap.contains(variableName);
}
inline QStringList fixEnvVariables(const QStringList &x)
{
QStringList ret;
foreach (const QString &str, x)
ret << Option::fixString(str, Option::FixEnvVars);
return ret;
}
QStringList ProFileEvaluator::values(const QString &variableName) const
{
return d->values(variableName);
return fixEnvVariables(d->values(variableName));
}
QStringList ProFileEvaluator::values(const QString &variableName, const ProFile *pro) const
{
return d->values(variableName, pro);
return fixEnvVariables(d->values(variableName, pro));
}
ProFileEvaluator::TemplateType ProFileEvaluator::templateType()
......
......@@ -173,7 +173,12 @@ static QStringList replaceInList(const QStringList &varList, const QRegExp &rege
}
*/
inline QStringList splitPathList(const QString paths)
inline QString fixEnvVariables(const QString &x)
{
return Option::fixString(x, Option::FixEnvVars);
}
inline QStringList splitPathList(const QString &paths)
{
return paths.split(Option::dirlist_sep);
}
......
......@@ -182,8 +182,8 @@
<key>CFBundleIdentifier</key>
<string>com.nokia.qtcreator</string>
<key>CFBundleVersion</key>
<string>0.9.1</string>
<string>0.9.2</string>
<key>CFBundleShortVersionString</key>
<string>0.9.1</string>
<string>0.9.2</string>
</dict>
</plist>
......@@ -138,10 +138,10 @@ public:
QString fileName() const
{ return _fileName; }
int line() const
unsigned line() const
{ return _line; }
int column() const
unsigned column() const
{ return _column; }
QString text() const
......@@ -150,8 +150,8 @@ public:
private:
int _level;
QString _fileName;
int _line;
int _column;
unsigned _line;
unsigned _column;
QString _text;
};
......
......@@ -70,6 +70,12 @@ QList<TypeOfExpression::Result> TypeOfExpression::operator()(const QString &expr
return resolveExpression(m_ast);
}
QString TypeOfExpression::preprocess(const QString &expression,
Document::Ptr document) const
{
return preprocessedExpression(expression, m_snapshot, document);
}
ExpressionAST *TypeOfExpression::ast() const
{
return m_ast;
......
......@@ -84,6 +84,8 @@ public:
Symbol *lastVisibleSymbol,
PreprocessMode mode = NoPreprocess);
QString preprocess(const QString &expression, Document::Ptr document) const;
/**
* Returns the AST of the last evaluated expression.
*/
......
<plugin name="BinEditor" version="0.9.1" compatVersion="0.9.1">
<plugin name="BinEditor" version="0.9.2" compatVersion="0.9.2">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Beta Version License</license>
<description>Binary editor component.</description>
<url>http://www.trolltech.com/</url>
<dependencyList>
<dependency name="Core" version="0.9.1"/>
<dependency name="TextEditor" version="0.9.1"/>
<dependency name="Core" version="0.9.2"/>
<dependency name="TextEditor" version="0.9.2"/>
</dependencyList>
</plugin>
<plugin name="Bookmarks" version="0.9.1" compatVersion="0.9.1">
<plugin name="Bookmarks" version="0.9.2" compatVersion="0.9.2">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Beta Version License</license>
<description>Bookmarks in text editors.</description>
<url>http://www.trolltech.com/</url>
<dependencyList>
<dependency name="TextEditor" version="0.9.1"/>
<dependency name="ProjectExplorer" version="0.9.1"/>
<dependency name="Core" version="0.9.1"/>
<dependency name="TextEditor" version="0.9.2"/>
<dependency name="ProjectExplorer" version="0.9.2"/>
<dependency name="Core" version="0.9.2"/>
</dependencyList>
</plugin>
<plugin name="CMakeProjectManager" version="0.9.1" compatVersion="0.9.1">
<plugin name="CMakeProjectManager" version="0.9.2" compatVersion="0.9.2">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>### TODO</license>
<description>CMake support</description>
<url>http://www.trolltech.com/</url>
<dependencyList>
<dependency name="TextEditor" version="0.9.1"/>
<dependency name="ProjectExplorer" version="0.9.1"/>
<dependency name="CppTools" version="0.9.1"/>
<dependency name="CppEditor" version="0.9.1"/>
<dependency name="Help" version="0.9.1"/>
<dependency name="TextEditor" version="0.9.2"/>
<dependency name="ProjectExplorer" version="0.9.2"/>
<dependency name="CppTools" version="0.9.2"/>
<dependency name="CppEditor" version="0.9.2"/>
<dependency name="Help" version="0.9.2"/>
</dependencyList>
</plugin>
<plugin name="Core" version="0.9.1" compatVersion="0.9.1">
<plugin name="Core" version="0.9.2" compatVersion="0.9.2">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Beta Version License</license>
......
......@@ -41,7 +41,7 @@ namespace Constants {
#define IDE_VERSION_MAJOR 0
#define IDE_VERSION_MINOR 9
#define IDE_VERSION_RELEASE 1
#define IDE_VERSION_RELEASE 2
#define STRINGIFY_INTERNAL(x) #x
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
......
<plugin name="CodePaster" version="0.9.1" compatVersion="0.9.1">
<plugin name="CodePaster" version="0.9.2" compatVersion="0.9.2">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Beta Version License</license>
<description>Codepaster plugin for pushing/fetching diff from server</description>
<url>http://www.trolltech.com/</url>
<dependencyList>
<dependency name="TextEditor" version="0.9.1"/>
<dependency name="ProjectExplorer" version="0.9.1"/>
<dependency name="Core" version="0.9.1"/>
<dependency name="TextEditor" version="0.9.2"/>
<dependency name="ProjectExplorer" version="0.9.2"/>
<dependency name="Core" version="0.9.2"/>
</dependencyList>
</plugin>
<plugin name="CppEditor" version="0.9.1" compatVersion="0.9.1">
<plugin name="CppEditor" version="0.9.2" compatVersion="0.9.2">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Beta Version License</license>
<description>C/C++ editor component.</description>
<url>http://www.trolltech.com/</url>
<dependencyList>
<dependency name="Core" version="0.9.1"/>
<dependency name="TextEditor" version="0.9.1"/>
<dependency name="CppTools" version="0.9.1"/>
<dependency name="Core" version="0.9.2"/>
<dependency name="TextEditor" version="0.9.2"/>
<dependency name="CppTools" version="0.9.2"/>
</dependencyList>
</plugin>
......@@ -53,6 +53,7 @@
#include <cplusplus/ExpressionUnderCursor.h>
#include <cplusplus/Overview.h>
#include <cplusplus/TypeOfExpression.h>
#include <cplusplus/SimpleLexer.h>
#include <QtGui/QToolTip>
#include <QtGui/QTextCursor>
......@@ -188,29 +189,36 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
if (!edit)
return;
const Snapshot documents = m_modelManager->snapshot();
const QString fileName = editor->file()->fileName();
Document::Ptr doc = documents.value(fileName);
if (! doc)
return; // nothing to do
QTextCursor tc(edit->document());
tc.setPosition(pos);
const unsigned lineNumber = tc.block().blockNumber() + 1;
const Snapshot documents = m_modelManager->snapshot();
// Find the last symbol up to the cursor position
int line = 0, column = 0;
editor->convertPosition(tc.position(), &line, &column);
Symbol *lastSymbol = doc->findSymbolAt(line, column);
const int lineNumber = tc.block().blockNumber() + 1;
const QString fileName = editor->file()->fileName();
Document::Ptr doc = documents.value(fileName);
if (doc) {
foreach (Document::DiagnosticMessage m, doc->diagnosticMessages()) {
if (m.line() == lineNumber) {
m_toolTip = m.text();
break;
}
TypeOfExpression typeOfExpression;
typeOfExpression.setSnapshot(documents);
foreach (Document::DiagnosticMessage m, doc->diagnosticMessages()) {
if (m.line() == lineNumber) {
m_toolTip = m.text();
break;
}
}
if (m_toolTip.isEmpty()) {
unsigned lineno = tc.blockNumber() + 1;
foreach (const Document::Include &incl, doc->includes()) {
if (lineno == incl.line()) {
m_toolTip = incl.fileName();
break;
}
if (m_toolTip.isEmpty()) {
foreach (const Document::Include &incl, doc->includes()) {
if (incl.line() == lineNumber) {
m_toolTip = incl.fileName();
break;
}
}
}
......@@ -233,43 +241,34 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
ExpressionUnderCursor expressionUnderCursor;
const QString expression = expressionUnderCursor(tc);
if (doc) {
// Find the last symbol up to the cursor position
int line = 0, column = 0;
editor->convertPosition(tc.position(), &line, &column);
Symbol *lastSymbol = doc->findSymbolAt(line, column);
TypeOfExpression typeOfExpression;
typeOfExpression.setSnapshot(documents);
QList<TypeOfExpression::Result> types = typeOfExpression(expression, doc, lastSymbol);
if (!types.isEmpty()) {
FullySpecifiedType firstType = types.first().first;
FullySpecifiedType docType = firstType;
if (const PointerType *pt = firstType->asPointerType()) {
docType = pt->elementType();
} else if (const ReferenceType *rt = firstType->asReferenceType()) {
docType = rt->elementType();
}
m_helpId = buildHelpId(docType, types.first().second);
QString displayName = buildHelpId(firstType, types.first().second);
if (!firstType->isClass() && !firstType->isNamedType()) {
Overview overview;
overview.setShowArgumentNames(true);
overview.setShowReturnTypes(true);
m_toolTip = overview.prettyType(firstType, displayName);
} else {
m_toolTip = m_helpId;
}
const QList<TypeOfExpression::Result> types =
typeOfExpression(expression, doc, lastSymbol);
if (!types.isEmpty()) {
FullySpecifiedType firstType = types.first().first;
FullySpecifiedType docType = firstType;