Commit efa5a7b6 authored by Eike Ziller's avatar Eike Ziller

Merge remote-tracking branch 'origin/4.4'

 Conflicts:
	qtcreator.pri

Change-Id: If5f4a9821a23ac0df81eb84b3980f9cf7ecd70ba
parents c8962c34 41127e0f
......@@ -187,11 +187,35 @@
\endlist
In addition, you can run static checks on the QML and JavaScript code in
your project to find common problems.
When using the Clang code model, errors and warnings are additionally marked
with icons and annotated. If a \l{http://clang.llvm.org/diagnostics.html}
{Clang fix-it} is available, you can execute it by clicking the
\inlineimage refactormarker.png
icon and pressing \key Enter.
In the following figure, a semicolon is missing at the end of the
line.
\image qtcreator-syntaxerror-clang.png
In the following figure, the variable is not used.
\image qtcreator-semanticerror-clang.png
To specify the position where the annotations are displayed, select
\uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} >
\uicontrol Display > \uicontrol {Annotations next to lines}, and then
select whether to display the annotations directly next to the code,
aligned to the right of the code, or in the right margin.
If you hide the annotations by deselecting the check box, you can move the
mouse pointer over an icon to view them.
\section1 Checking JSON Data Structure
You can run static checks on the QML and JavaScript code in
your project to find common problems.
\QC validates instances of JSON entities against
\l{http://tools.ietf.org/html/draft-zyp-json-schema-03}
{A JSON Media Type for Describing the Structure and Meaning of JSON Documents}.
......@@ -1956,6 +1980,9 @@
\section1 Renaming Symbols
You can rename symbols in all files in a project. When you rename a class,
you can also change filenames that match the class name.
To rename a specific symbol in a Qt project:
\list 1
......@@ -1973,15 +2000,18 @@
\image qtcreator-refactoring-replace.png
\li To replace all selected instances, enter the name of the new symbol
in the \uicontrol {Replace with} text box and click
\uicontrol Replace.
in the \uicontrol {Replace with} text box.
To omit an instance, uncheck the check-box next to the instance.
\li If the symbol is a class, select the \uicontrol {Rename files} check
box to also change the filenames that match the class name.
\li Select \uicontrol Replace.
\note This action replaces all selected instances of the symbol in
all files listed in the \uicontrol {Search Results} pane. You cannot
undo this action.
\endlist
\note Renaming local symbols does not open the \uicontrol {Search Results}
......
......@@ -17,6 +17,8 @@ Module {
property string qtcreator_compat_version: ide_compat_version_major + '.'
+ ide_compat_version_minor + '.' + ide_compat_version_release
property string qtcreator_copyright_year: '2017'
property string libDirName: "lib"
property string ide_app_path: qbs.targetOS.contains("macos") ? "" : "bin"
property string ide_app_target: qbs.targetOS.contains("macos") ? "Qt Creator" : "qtcreator"
......
......@@ -5,6 +5,7 @@ QTCREATOR_VERSION = 4.4.82
QTCREATOR_COMPAT_VERSION = 4.4.82
VERSION = $$QTCREATOR_VERSION
QTCREATOR_DISPLAY_VERSION = 4.5.0-beta1
QTCREATOR_COPYRIGHT_YEAR = 2017
BINARY_ARTIFACTS_BRANCH = master
CONFIG += c++14
......
......@@ -94,7 +94,7 @@ runCodeCompletion()
if [ -n "${CINDEXTEST_EXEC}" ]; then
command="${CINDEXTEST_EXEC} -code-completion-at=${FILE}:${LINE}:${COLUMN} ${FILE}"
else
command="${CLANG_EXEC} -cc1 -code-completion-at ${FILE}:${LINE}:${COLUMN} ${FILE}"
command="${CLANG_EXEC} -fsyntax-only -Xclang -code-completion-at -Xclang ${FILE}:${LINE}:${COLUMN} ${FILE}"
fi
echo "Command: $command"
eval $command
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a C++ header and a source file for a new class that you can add to a C++ project.",
"trDisplayName": "C++ Class",
"trDisplayCategory": "C++",
"iconText": "h/cpp",
"enabled": "%{JS: [ %{Plugins} ].indexOf('CppEditor') >= 0}",
"options":
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates new Python class file.",
"trDisplayName": "Python Class",
"trDisplayCategory": "Python",
"iconText": "py",
"enabled": "%{JS: [ %{Plugins} ].indexOf('PythonEditor') >= 0}",
"options":
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a Qt Quick Designer UI form along with a matching QML file for implementation purposes. You can add the form and file to an existing Qt Quick Project.",
"trDisplayName": "QtQuick UI File",
"trDisplayCategory": "Qt",
"iconText": "ui.qml",
"featuresRequired": [ "QtSupport.Wizards.FeatureQtQuick.UiFiles" ],
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmlJSEditor') >= 0}",
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a C++ header file that you can add to a C++ project.",
"trDisplayName": "C++ Header File",
"trDisplayCategory": "C++",
"iconText": "h",
"enabled": "%{JS: [ %{Plugins} ].indexOf('CppEditor') >= 0}",
"options": { "key": "FileName", "value": "%{JS: Cpp.fileName('%{TargetPath}', '%{JS: Util.preferredSuffix('text/x-c++hdr')}')}" },
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a C++ source file that you can add to a C++ project.",
"trDisplayName": "C++ Source File",
"trDisplayCategory": "C++",
"iconText": "cpp",
"enabled": "%{JS: [ %{Plugins} ].indexOf('CppEditor') >= 0}",
"options": { "key": "FileName", "value": "%{JS: Cpp.fileName('%{TargetPath}', '%{JS: Util.preferredSuffix('text/x-c++src')}')}" },
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a Qt Designer form that you can add to a Qt Widget Project. This is useful if you already have an existing class for the UI business logic.",
"trDisplayName": "Qt Designer Form",
"trDisplayCategory": "Qt",
"iconText": "ui",
"enabled": "%{JS: [ %{Plugins} ].indexOf('Designer') >= 0}",
"options": [
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a fragment shader in the Desktop OpenGL Shading Language (GLSL). Fragment shaders generate the final pixel colors for triangles, points and lines rendered with OpenGL.",
"trDisplayName": "Fragment Shader (Desktop OpenGL)",
"trDisplayCategory": "GLSL",
"iconText": "frag",
"platformIndependent": true,
"enabled": "%{JS: [ %{Plugins} ].indexOf('GLSLEditor') >= 0}",
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a vertex shader in the Desktop OpenGL Shading Language (GLSL). Vertex shaders transform the positions, normals and texture coordinates of triangles, points and lines rendered with OpenGL.",
"trDisplayName": "Vertex Shader (Desktop OpenGL)",
"trDisplayCategory": "GLSL",
"iconText": "vert",
"platformIndependent": true,
"enabled": "%{JS: [ %{Plugins} ].indexOf('GLSLEditor') >= 0}",
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a fragment shader in the OpenGL/ES 2.0 Shading Language (GLSL/ES). Fragment shaders generate the final pixel colors for triangles, points and lines rendered with OpenGL.",
"trDisplayName": "Fragment Shader (OpenGL/ES 2.0)",
"trDisplayCategory": "GLSL",
"iconText": "fsh",
"platformIndependent": true,
"enabled": "%{JS: [ %{Plugins} ].indexOf('GLSLEditor') >= 0}",
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a vertex shader in the OpenGL/ES 2.0 Shading Language (GLSL/ES). Vertex shaders transform the positions, normals and texture coordinates of triangles, points and lines rendered with OpenGL.",
"trDisplayName": "Vertex Shader (OpenGL/ES 2.0)",
"trDisplayCategory": "GLSL",
"iconText": "vsh",
"platformIndependent": true,
"enabled": "%{JS: [ %{Plugins} ].indexOf('GLSLEditor') >= 0}",
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a Java file with boilerplate code.",
"trDisplayName": "Java File",
"trDisplayCategory": "Java",
"iconText": "java",
"enabled": "%{JS: [ %{Plugins} ].indexOf('Android') >= 0}",
"options": [ { "key": "ClassName", "value": "%{JS: '%{FileName}'.charAt(0).toUpperCase() + '%{FileName}'.substr(1)}" } ],
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a JavaScript file.",
"trDisplayName": "JS File",
"trDisplayCategory": "Qt",
"iconText": "js",
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmlJSEditor') >= 0}",
"pages" :
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a new empty model with an empty diagram.",
"trDisplayName": "Model",
"trDisplayCategory": "Modeling",
"iconText": "qmodel",
"platformIndependent": true,
"enabled": "%{JS: [ %{Plugins} ].indexOf('ModelEditor') >= 0}",
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates an empty Python script file using UTF-8 charset.",
"trDisplayName": "Python File",
"trDisplayCategory": "Python",
"iconText": "py",
"enabled": "%{JS: [ %{Plugins} ].indexOf('PythonEditor') >= 0}",
"pages" :
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a Qt Resource file (.qrc).",
"trDisplayName": "Qt Resource File",
"trDisplayCategory": "Qt",
"iconText": "qrc",
"enabled": "%{JS: [ %{Plugins} ].indexOf('ResourceEditor') >= 0}",
"pages" :
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a QML file with boilerplate code, starting with \"import QtQuick 2.0\".",
"trDisplayName": "QML File (Qt Quick 2)",
"trDisplayCategory": "Qt",
"iconText": "qml",
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmlJSEditor') >= 0}",
"pages" :
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates a new empty state chart.",
"trDisplayName": "State Chart",
"trDisplayCategory": "Modeling",
"iconText": "scxml",
"platformIndependent": true,
"enabled": "%{JS: [ %{Plugins} ].indexOf('QtSupport') >= 0}",
......
......@@ -6,6 +6,7 @@
"trDescription": "Creates an empty file.",
"trDisplayName": "Empty File",
"trDisplayCategory": "General",
"iconText": "txt",
"platformIndependent": true,
"enabled": "%{JS: [ %{Plugins} ].indexOf('TextEditor') >= 0}",
......
......@@ -20,6 +20,12 @@ QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
include($$QT_BREAKPAD_ROOT_PATH/qtbreakpad.pri)
}
win32 {
# We need the version in two separate formats for the .rc file
# RC_VERSION=4,3,82,0 (quadruple)
# RC_VERSION_STRING="4.4.0-beta1" (free text)
DEFINES += RC_VERSION=$$replace(QTCREATOR_VERSION, "\\.", ","),0 \
RC_VERSION_STRING=\\\"$${QTCREATOR_DISPLAY_VERSION}\\\" \
RC_COPYRIGHT='"\\\"2008-$${QTCREATOR_COPYRIGHT_YEAR} The Qt Company Ltd\\\""'
RC_FILE = qtcreator.rc
} else:macx {
LIBS += -framework CoreFoundation
......
......@@ -41,7 +41,6 @@ QtcProduct {
"Info.plist",
"main.cpp",
"qtcreator.xcassets",
"qtcreator.rc",
"../shared/qtsingleapplication/qtsingleapplication.h",
"../shared/qtsingleapplication/qtsingleapplication.cpp",
"../shared/qtsingleapplication/qtlocalpeer.h",
......@@ -51,6 +50,16 @@ QtcProduct {
"../tools/qtcreatorcrashhandler/crashhandlersetup.h"
]
Group {
// We need the version in two separate formats for the .rc file
// RC_VERSION=4,3,82,0 (quadruple)
// RC_VERSION_STRING="4.4.0-beta1" (free text)
cpp.defines: outer.concat(["RC_VERSION=" + qtc.qtcreator_version.replace(/\./g, ",") + ",0",
"RC_VERSION_STRING=\"" + qtc.qtcreator_display_version + "\"",
"RC_COPYRIGHT=\"2008-" + qtc.qtcreator_copyright_year + " The Qt Company Ltd\""])
files: "qtcreator.rc"
}
Group {
name: "qtcreator.sh"
condition: qbs.targetOS.contains("unix") && !qbs.targetOS.contains("macos")
......
......@@ -42,7 +42,7 @@ namespace Constants {
const char * const IDE_VERSION_LONG = IDE_VERSION_STR;
const char * const IDE_VERSION_DISPLAY = STRINGIFY(IDE_VERSION_DISPLAY_DEF);
const char * const IDE_AUTHOR = \"The Qt Company Ltd\";
const char * const IDE_YEAR = \"2017\";
const char * const IDE_YEAR = \"$${QTCREATOR_COPYRIGHT_YEAR}\";
#ifdef IDE_REVISION
const char * const IDE_REVISION_STR = STRINGIFY(IDE_REVISION);
......
......@@ -42,6 +42,8 @@ Product {
+ product.moduleProperty("qtc", "ide_version_minor") + "\n");
content = content.replace(/(\n#define IDE_VERSION_RELEASE) .+\n/, "$1 "
+ product.moduleProperty("qtc", "ide_version_release") + "\n");
content = content.replace(/(\n#define IDE_COPYRIGHT_YEAR) .+\n/, "$1 "
+ product.moduleProperty("qtc", "qtcreator_copyright_year") + "\n");
file = new TextFile(output.filePath, TextFile.WriteOnly);
file.truncate();
file.write(content);
......
#include <windows.h>
IDI_ICON1 ICON DISCARDABLE "qtcreator.ico"
IDI_ICON2 ICON DISCARDABLE "winicons/c.ico"
IDI_ICON3 ICON DISCARDABLE "winicons/cpp.ico"
......@@ -6,3 +8,25 @@ IDI_ICON5 ICON DISCARDABLE "winicons/ui.ico"
IDI_ICON6 ICON DISCARDABLE "winicons/pro.ico"
IDI_ICON7 ICON DISCARDABLE "winicons/pri.ico"
IDI_ICON8 ICON DISCARDABLE "winicons/qml.ico"
VS_VERSION_INFO VERSIONINFO
FILEVERSION RC_VERSION
PRODUCTVERSION RC_VERSION
{
BLOCK "StringFileInfo"
{
// U.S. English - Windows, Multilingual
BLOCK "040904E4"
{
VALUE "FileDescription", "Qt Creator"
VALUE "FileVersion", RC_VERSION_STRING
VALUE "ProductName", "Qt Creator"
VALUE "ProductVersion", RC_VERSION_STRING
VALUE "LegalCopyright", RC_COPYRIGHT
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x409, 1252 // 1252 = 0x04E4
}
}
......@@ -55,7 +55,7 @@ public:
return m_contextType;
}
Utils::SmallString contextTypeText() const;
CMBIPC_EXPORT Utils::SmallString contextTypeText() const;
const Utils::SmallStringVector &arguments() const
{
......
......@@ -33,8 +33,8 @@ namespace ClangBackEnd {
QDebug operator<<(QDebug debug, const DynamicASTMatcherDiagnosticMessageContainer &container)
{
debug.nospace() << "DynamicASTMatcherDiagnosticMessageContainer("
<< container.sourceRange() << ", "
<< container.errorTypeText() << ", "
<< container.sourceRange() << ", "
<< container.arguments()
<< ")";
......
......@@ -55,7 +55,7 @@ public:
return m_errorType;
}
Utils::SmallString errorTypeText() const;
CMBIPC_EXPORT Utils::SmallString errorTypeText() const;
const Utils::SmallStringVector &arguments() const
{
......
......@@ -34,6 +34,8 @@
#include <QChar>
#include <QDebug>
#include <utils/algorithm.h>
using namespace CPlusPlus;
enum { MAX_NUM_LINES = 20 };
......@@ -135,16 +137,215 @@ static const Token tokenAtPosition(const Tokens &tokens, const unsigned pos)
return Token();
}
static int tokenIndexBeforePosition(const Tokens &tokens, unsigned pos)
{
for (int i = tokens.size() - 1; i >= 0; --i) {
if (tokens[i].utf16charsBegin() < pos)
return i;
}
return -1;
}
static bool isCursorAtEndOfLineButMaybeBeforeComment(const Tokens &tokens, int pos)
{
int index = tokenIndexBeforePosition(tokens, uint(pos));
if (index == -1 || index >= tokens.size())
return false;
do {
++index;
} while (index < tokens.size() && tokens[index].isComment());
return index >= tokens.size();
}
// 10.6.1 Attribute syntax and semantics
// This does not handle alignas() since it is not needed for the namespace case.
static int skipAttributeSpecifierSequence(const Tokens &tokens, int index)
{
// [[ attribute-using-prefixopt attribute-list ]]
if (index >= 1 && tokens[index].is(T_RBRACKET) && tokens[index - 1].is(T_RBRACKET)) {
// Skip everything within [[ ]]
for (int i = index - 2; i >= 0; --i) {
if (i >= 1 && tokens[i].is(T_LBRACKET) && tokens[i - 1].is(T_LBRACKET))
return i - 2;
}
return -1;
}
return index;
}
static int skipNamespaceName(const Tokens &tokens, int index)
{
if (index >= tokens.size())
return -1;
if (!tokens[index].is(T_IDENTIFIER))
return index;
// Accept
// SomeName
// Some::Nested::Name
bool expectIdentifier = false;
for (int i = index - 1; i >= 0; --i) {
if (expectIdentifier) {
if (tokens[i].is(T_IDENTIFIER))
expectIdentifier = false;
else
return -1;
} else if (tokens[i].is(T_COLON_COLON)) {
expectIdentifier = true;
} else {
return i;
}
}
return index;
}
// 10.3.1 Namespace definition
static bool isAfterNamespaceDefinition(const Tokens &tokens, int position)
{
int index = tokenIndexBeforePosition(tokens, uint(position));
if (index == -1)
return false;
// Handle optional name
index = skipNamespaceName(tokens, index);
if (index == -1)
return false;
// Handle optional attribute specifier sequence
index = skipAttributeSpecifierSequence(tokens, index);
if (index == -1)
return false;
return index >= 0 && tokens[index].is(T_NAMESPACE);
}
static int isEmptyOrWhitespace(const QString &text)
{
return Utils::allOf(text, [](const QChar &c) {return c.isSpace(); });
}
static QTextBlock previousNonEmptyBlock(const QTextBlock &currentBlock)
{
QTextBlock block = currentBlock.previous();
forever {
if (!block.isValid() || !isEmptyOrWhitespace(block.text()))
return block;
block = block.previous();
}
}
static QTextBlock nextNonEmptyBlock(const QTextBlock &currentBlock)
{
QTextBlock block = currentBlock.next();
forever {
if (!block.isValid() || !isEmptyOrWhitespace(block.text()))
return block;
block = block.next();
}
}
static bool allowAutoClosingBraceAtEmptyLine(
const QTextBlock &block,
MatchingText::IsNextBlockDeeperIndented isNextDeeperIndented)
{
QTextBlock previousBlock = previousNonEmptyBlock(block);
if (!previousBlock.isValid())
return false; // Nothing before
QTextBlock nextBlock = nextNonEmptyBlock(block);
if (!nextBlock.isValid())
return true; // Nothing behind
if (isNextDeeperIndented && isNextDeeperIndented(previousBlock))
return false; // Before indented
const QString trimmedText = previousBlock.text().trimmed();
return !trimmedText.endsWith(';')
&& !trimmedText.endsWith('{')
&& !trimmedText.endsWith('}');
}
static Tokens getTokens(const QTextCursor &cursor, int &prevState)
{
LanguageFeatures features;
features.qtEnabled = false;
features.qtKeywordsEnabled = false;
features.qtMocRunEnabled = false;
features.cxx11Enabled = true;
features.cxxEnabled = true;
features.c99Enabled = true;
features.objCEnabled = true;
SimpleLexer tokenize;
tokenize.setLanguageFeatures(features);
prevState = BackwardsScanner::previousBlockState(cursor.block()) & 0xFF;
return tokenize(cursor.block().text(), prevState);
}
static QChar firstNonSpace(const QTextCursor &cursor)
{
int position = cursor.position();
QChar ch = cursor.document()->characterAt(position);
while (ch.isSpace())
ch = cursor.document()->characterAt(++position);
return ch;
}
static bool allowAutoClosingBraceByLookahead(const QTextCursor &cursor)
{
const QChar lookAhead = firstNonSpace(cursor);
if (lookAhead.isNull())
return true;
switch (lookAhead.unicode()) {
case ';': case ',':
case ')': case '}': case ']':
return true;
}
return false;
}
static bool allowAutoClosingBrace(const QTextCursor &cursor,
MatchingText::IsNextBlockDeeperIndented isNextIndented)
{
if (MatchingText::isInCommentHelper(cursor))
return false;
const QTextBlock block = cursor.block();
if (isEmptyOrWhitespace(block.text()))
return allowAutoClosingBraceAtEmptyLine(cursor.block(), isNextIndented);
int prevState;
const Tokens tokens = getTokens(cursor, prevState);
if (isAfterNamespaceDefinition(tokens, cursor.positionInBlock()))
return false;
if (isCursorAtEndOfLineButMaybeBeforeComment(tokens, cursor.positionInBlock()))
return !(isNextIndented && isNextIndented(block));
return allowAutoClosingBraceByLookahead(cursor);
}
bool MatchingText::contextAllowsAutoParentheses(const QTextCursor &cursor,
const QString &textToInsert)
const QString &textToInsert,
IsNextBlockDeeperIndented isNextIndented)
{
QChar ch;
if (!textToInsert.isEmpty())
ch = textToInsert.at(0);
if (ch == QLatin1Char('{') && cursor.block().text().trimmed().isEmpty())
return false; // User just might want to wrap up some lines.
if (ch == QLatin1Char('{'))
return allowAutoClosingBrace(cursor, isNextIndented);
if (!shouldInsertMatchingText(cursor) && ch != QLatin1Char('\'') && ch != QLatin1Char('"'))
return false;
......@@ -198,24 +399,6 @@ bool MatchingText::shouldInsertMatchingText(QChar lookAhead)
} // switch
}
static Tokens getTokens(const QTextCursor &cursor, int &prevState)
{
LanguageFeatures features;
features.qtEnabled = false;
features.qtKeywordsEnabled = false;
features.qtMocRunEnabled = false;
features.cxx11Enabled = true;
features.cxxEnabled = true;
features.c99Enabled = true;
features.objCEnabled = true;
SimpleLexer tokenize;
tokenize.setLanguageFeatures(features);
prevState = BackwardsScanner::previousBlockState(cursor.block()) & 0xFF;
return tokenize(cursor.block().text(), prevState);
}
bool MatchingText::isInCommentHelper(const QTextCursor &cursor, Token *retToken)
{
int prevState = 0;
......
......@@ -30,7 +30,10 @@
#include <cplusplus/Token.h>
#include <cplusplus/CPlusPlusForwardDeclarations.h>
#include <functional>
QT_FORWARD_DECLARE_CLASS(QTextCursor)
QT_FORWARD_DECLARE_CLASS(QTextBlock)
QT_FORWARD_DECLARE_CLASS(QChar)
namespace CPlusPlus {
......@@ -38,8 +41,11 @@ namespace CPlusPlus {
class CPLUSPLUS_EXPORT MatchingText
{
public:
using IsNextBlockDeeperIndented = std::function<bool(const QTextBlock &textBlock)>;
static bool contextAllowsAutoParentheses(const QTextCursor &cursor,
const QString &textToInsert);