Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Marco Bubke
flatpak-qt-creator
Commits
49c43aaa
Commit
49c43aaa
authored
Feb 03, 2010
by
Christian Kamm
Browse files
Get rid of Environment, introduce external ScopeChain in Link.
Done-with: Roberto
parent
ba18e700
Changes
8
Hide whitespace changes
Inline
Side-by-side
src/libs/qmljs/qmljscheck.cpp
View file @
49c43aaa
...
...
@@ -29,6 +29,7 @@
#include
"qmljscheck.h"
#include
"qmljsinterpreter.h"
#include
"qmljslink.h"
#include
"parser/qmljsparser_p.h"
#include
"parser/qmljsast_p.h"
#include
<QtCore/QDebug>
...
...
@@ -36,10 +37,10 @@
using
namespace
QmlJS
;
using
namespace
QmlJS
::
Interpreter
;
Check
::
Check
(
Interpreter
::
Eng
in
e
*
engine
,
Interpreter
::
Context
*
context
)
:
_engine
(
engine
),
_
context
(
context
),
_scope
(
engine
->
globalObject
()),
Check
::
Check
(
L
in
k
*
link
)
:
_engine
(
link
->
engine
()
),
_
link
(
link
),
_scope
(
_
engine
->
globalObject
()),
_result
(
0
)
{
}
...
...
@@ -48,12 +49,9 @@ Check::~Check()
{
}
const
Interpreter
::
Value
*
Check
::
operator
()(
AST
::
Node
*
ast
,
const
Interpreter
::
ObjectValue
*
scope
)
const
Interpreter
::
Value
*
Check
::
operator
()(
AST
::
Node
*
ast
)
{
const
Interpreter
::
ObjectValue
*
previousScope
=
switchScope
(
scope
);
const
Interpreter
::
Value
*
result
=
check
(
ast
);
(
void
)
switchScope
(
previousScope
);
return
result
;
return
check
(
ast
);
}
const
Interpreter
::
Value
*
Check
::
check
(
AST
::
Node
*
ast
)
...
...
@@ -68,7 +66,7 @@ const Interpreter::Value *Check::check(AST::Node *ast)
const
Value
*
result
=
switchResult
(
previousResult
);
if
(
const
Reference
*
ref
=
value_cast
<
const
Reference
*>
(
result
))
result
=
ref
->
value
(
_context
);
result
=
ref
->
value
(
_
link
->
context
()
);
if
(
!
result
)
result
=
_engine
->
undefinedValue
();
...
...
@@ -167,7 +165,7 @@ bool Check::visit(AST::UiQualifiedId *ast)
if
(
!
ast
->
name
)
return
false
;
const
Value
*
value
=
_
scope
->
lookup
(
ast
->
name
->
asString
());
const
Value
*
value
=
_
link
->
lookup
(
ast
->
name
->
asString
());
if
(
!
ast
->
next
)
{
_result
=
value
;
...
...
@@ -215,7 +213,7 @@ bool Check::visit(AST::IdentifierExpression *ast)
if
(
!
ast
->
name
)
return
false
;
_result
=
_
scope
->
lookup
(
ast
->
name
->
asString
());
_result
=
_
link
->
lookup
(
ast
->
name
->
asString
());
return
false
;
}
...
...
src/libs/qmljs/qmljscheck.h
View file @
49c43aaa
...
...
@@ -35,6 +35,8 @@
namespace
QmlJS
{
class
Link
;
namespace
Interpreter
{
class
Engine
;
class
Context
;
...
...
@@ -46,10 +48,10 @@ namespace Interpreter {
class
QMLJS_EXPORT
Check
:
protected
AST
::
Visitor
{
public:
Check
(
Interpreter
::
Eng
in
e
*
engine
,
Interpreter
::
Context
*
context
);
Check
(
L
in
k
*
link
);
virtual
~
Check
();
const
Interpreter
::
Value
*
operator
()(
AST
::
Node
*
ast
,
const
Interpreter
::
ObjectValue
*
scope
);
const
Interpreter
::
Value
*
operator
()(
AST
::
Node
*
ast
);
protected:
void
accept
(
AST
::
Node
*
node
);
...
...
@@ -156,7 +158,7 @@ protected:
private:
QmlJS
::
Document
::
Ptr
_doc
;
Interpreter
::
Engine
*
_engine
;
Interpreter
::
Context
*
_context
;
Link
*
_link
;
const
Interpreter
::
ObjectValue
*
_scope
;
const
Interpreter
::
Value
*
_result
;
};
...
...
src/libs/qmljs/qmljsinterpreter.cpp
View file @
49c43aaa
...
...
@@ -622,39 +622,6 @@ const Reference *Value::asReference() const
return
0
;
}
////////////////////////////////////////////////////////////////////////////////
// Environment
////////////////////////////////////////////////////////////////////////////////
Environment
::
Environment
()
{
}
Environment
::~
Environment
()
{
}
const
Environment
*
Environment
::
parent
()
const
{
return
0
;
}
const
Value
*
Environment
::
lookup
(
const
QString
&
name
)
const
{
if
(
const
Value
*
member
=
lookupMember
(
name
))
return
member
;
else
if
(
const
Environment
*
p
=
parent
())
return
p
->
lookup
(
name
);
else
return
0
;
}
const
Value
*
Environment
::
lookupMember
(
const
QString
&
)
const
{
return
0
;
}
////////////////////////////////////////////////////////////////////////////////
// Values
////////////////////////////////////////////////////////////////////////////////
...
...
@@ -788,8 +755,7 @@ bool MemberProcessor::processGeneratedSlot(const QString &, const Value *)
ObjectValue
::
ObjectValue
(
Engine
*
engine
)
:
_engine
(
engine
),
_prototype
(
0
),
_scope
(
0
)
_prototype
(
0
)
{
engine
->
registerObject
(
this
);
}
...
...
@@ -818,16 +784,6 @@ const ObjectValue *ObjectValue::prototype() const
return
_prototype
;
}
const
ObjectValue
*
ObjectValue
::
scope
()
const
{
return
_scope
;
}
void
ObjectValue
::
setScope
(
const
ObjectValue
*
scope
)
{
_scope
=
scope
;
}
void
ObjectValue
::
setProperty
(
const
QString
&
name
,
const
Value
*
value
)
{
_members
[
name
]
=
value
;
...
...
@@ -893,11 +849,6 @@ void ObjectValue::processMembers(MemberProcessor *processor) const
}
}
const
Environment
*
ObjectValue
::
parent
()
const
{
return
_scope
;
}
const
Value
*
ObjectValue
::
lookupMember
(
const
QString
&
name
)
const
{
if
(
const
Value
*
m
=
_members
.
value
(
name
))
...
...
src/libs/qmljs/qmljsinterpreter.h
View file @
49c43aaa
...
...
@@ -150,20 +150,6 @@ template <> Q_INLINE_TEMPLATE const Reference *value_cast(const Value *v)
else
return
0
;
}
////////////////////////////////////////////////////////////////////////////////
// Execution environment
////////////////////////////////////////////////////////////////////////////////
class
QMLJS_EXPORT
Environment
{
public:
Environment
();
virtual
~
Environment
();
virtual
const
Environment
*
parent
()
const
;
virtual
const
Value
*
lookup
(
const
QString
&
name
)
const
;
virtual
const
Value
*
lookupMember
(
const
QString
&
name
)
const
;
};
////////////////////////////////////////////////////////////////////////////////
// Value nodes
////////////////////////////////////////////////////////////////////////////////
...
...
@@ -250,7 +236,7 @@ public:
virtual
void
accept
(
ValueVisitor
*
)
const
;
};
class
QMLJS_EXPORT
ObjectValue
:
public
Value
,
public
Environment
class
QMLJS_EXPORT
ObjectValue
:
public
Value
{
public:
ObjectValue
(
Engine
*
engine
);
...
...
@@ -264,17 +250,12 @@ public:
const
ObjectValue
*
prototype
()
const
;
void
setPrototype
(
const
ObjectValue
*
prototype
);
const
ObjectValue
*
scope
()
const
;
void
setScope
(
const
ObjectValue
*
scope
);
virtual
void
processMembers
(
MemberProcessor
*
processor
)
const
;
virtual
const
Value
*
property
(
const
QString
&
name
)
const
;
virtual
void
setProperty
(
const
QString
&
name
,
const
Value
*
value
);
virtual
void
removeProperty
(
const
QString
&
name
);
// Environment interface
virtual
const
Environment
*
parent
()
const
;
virtual
const
Value
*
lookupMember
(
const
QString
&
name
)
const
;
// Value interface
...
...
@@ -287,7 +268,6 @@ private:
private:
Engine
*
_engine
;
const
ObjectValue
*
_prototype
;
const
ObjectValue
*
_scope
;
QHash
<
QString
,
const
Value
*>
_members
;
QString
_className
;
};
...
...
src/libs/qmljs/qmljslink.cpp
View file @
49c43aaa
...
...
@@ -24,69 +24,81 @@ Link::Link(Document::Ptr currentDoc, const Snapshot &snapshot, Interpreter::Engi
Link
::~
Link
()
{
// unset all prototypes
and scopes
// unset all prototypes
foreach
(
Document
::
Ptr
doc
,
_docs
)
{
BindPtr
bind
=
doc
->
bind
();
if
(
doc
->
qmlProgram
())
{
bind
->
_idEnvironment
->
setScope
(
0
);
bind
->
_functionEnvironment
->
setScope
(
0
);
foreach
(
ObjectValue
*
object
,
bind
->
_qmlObjects
)
{
object
->
setPrototype
(
0
);
object
->
setScope
(
0
);
}
}
else
if
(
doc
->
jsProgram
())
{
bind
->
_rootObjectValue
->
setScope
(
0
);
}
}
}
static
ObjectValue
*
pushScope
(
ObjectValue
*
next
,
ObjectValue
*
onto
)
Context
*
Link
::
context
(
)
{
onto
->
setScope
(
next
);
return
next
;
return
&
_context
;
}
Context
*
Link
::
co
ntext
()
Link
::
ScopeChain
Link
::
s
co
peChain
()
const
{
return
&
_context
;
return
_scopeChain
;
}
ObjectValue
*
Link
::
scopeChainAt
(
Document
::
Ptr
doc
,
Node
*
currentObject
)
Interpreter
::
Engine
*
Link
::
engine
(
)
{
BindPtr
bind
=
doc
->
bind
();
return
_interp
;
}
ObjectValue
*
scopeObject
=
0
;
if
(
UiObjectDefinition
*
definition
=
cast
<
UiObjectDefinition
*>
(
currentObject
))
scopeObject
=
bind
->
_qmlObjects
.
value
(
definition
);
void
Link
::
scopeChainAt
(
Document
::
Ptr
doc
,
Node
*
currentObject
)
{
_scopeChain
.
clear
();
if
(
!
doc
)
{
_scopeChain
.
append
(
_interp
->
globalObject
());
return
;
}
if
(
!
scopeObject
)
return
bind
->
_interp
.
globalObject
();
BindPtr
bind
=
doc
->
bind
();
// Build the scope chain.
ObjectValue
*
scopeStart
=
_typeEnvironments
.
value
(
doc
.
data
());
ObjectValue
*
scope
=
scopeStart
;
scope
=
pushScope
(
bind
->
_idEnvironment
,
scope
);
scope
=
pushScope
(
bind
->
_functionEnvironment
,
scope
);
_scopeChain
.
append
(
_typeEnvironments
.
value
(
doc
.
data
()));
_scopeChain
.
append
(
bind
->
_idEnvironment
);
_scopeChain
.
append
(
bind
->
_functionEnvironment
);
foreach
(
const
QString
&
scriptFile
,
doc
->
bind
()
->
includedScripts
())
{
if
(
Document
::
Ptr
scriptDoc
=
_snapshot
.
document
(
scriptFile
))
{
if
(
scriptDoc
->
jsProgram
())
{
scope
=
pushScope
(
scriptDoc
->
bind
()
->
_rootObjectValue
,
scope
);
_
scope
Chain
.
append
(
scriptDoc
->
bind
()
->
_rootObjectValue
);
}
}
}
scope
=
pushScope
(
scopeObject
,
scope
);
if
(
scopeObject
!=
bind
->
_rootObjectValue
)
scope
=
pushScope
(
bind
->
_rootObjectValue
,
scope
);
scope
=
pushScope
(
bind
->
_interp
.
globalObject
(),
scope
);
if
(
UiObjectDefinition
*
definition
=
cast
<
UiObjectDefinition
*>
(
currentObject
))
{
ObjectValue
*
scopeObject
=
bind
->
_qmlObjects
.
value
(
definition
);
_scopeChain
.
append
(
scopeObject
);
// ### FIXME: should add the root regardless
if
(
scopeObject
!=
bind
->
_rootObjectValue
)
_scopeChain
.
append
(
bind
->
_rootObjectValue
);
}
_scopeChain
.
append
(
bind
->
_interp
.
globalObject
());
// May want to link to instantiating components from here.
}
const
Value
*
Link
::
lookup
(
const
QString
&
name
)
const
{
foreach
(
const
ObjectValue
*
scope
,
_scopeChain
)
{
if
(
const
Value
*
member
=
scope
->
lookupMember
(
name
))
{
return
member
;
}
}
return
scopeStart
;
return
_interp
->
undefinedValue
()
;
}
void
Link
::
linkImports
()
...
...
src/libs/qmljs/qmljslink.h
View file @
49c43aaa
...
...
@@ -18,15 +18,22 @@ namespace QmlJS {
*/
class
QMLJS_EXPORT
Link
{
public:
typedef
QList
<
const
Interpreter
::
ObjectValue
*>
ScopeChain
;
public:
// Link all documents in snapshot reachable from doc.
Link
(
Document
::
Ptr
doc
,
const
Snapshot
&
snapshot
,
Interpreter
::
Engine
*
interp
);
~
Link
();
Interpreter
::
Context
*
context
();
ScopeChain
scopeChain
()
const
;
Interpreter
::
Engine
*
engine
();
// Get the scope chain for the currentObject inside doc.
Interpreter
::
ObjectValue
*
scopeChainAt
(
Document
::
Ptr
doc
,
AST
::
Node
*
currentObject
);
void
scopeChainAt
(
Document
::
Ptr
doc
,
AST
::
Node
*
currentObject
);
const
Interpreter
::
Value
*
lookup
(
const
QString
&
name
)
const
;
private:
static
QList
<
Document
::
Ptr
>
reachableDocuments
(
Document
::
Ptr
startDoc
,
const
Snapshot
&
snapshot
);
...
...
@@ -48,6 +55,7 @@ private:
Interpreter
::
Context
_context
;
QList
<
Document
::
Ptr
>
_docs
;
QHash
<
Document
*
,
Interpreter
::
ObjectValue
*>
_typeEnvironments
;
ScopeChain
_scopeChain
;
};
}
// namespace QmlJS
...
...
src/plugins/qmljseditor/qmlcodecompletion.cpp
View file @
49c43aaa
...
...
@@ -129,10 +129,12 @@ class EnumerateProperties: private Interpreter::MemberProcessor
QSet
<
const
Interpreter
::
ObjectValue
*>
_processed
;
QHash
<
QString
,
const
Interpreter
::
Value
*>
_properties
;
bool
_globalCompletion
;
Link
*
_link
;
public:
EnumerateProperties
()
:
_globalCompletion
(
false
)
EnumerateProperties
(
Link
*
link
)
:
_globalCompletion
(
false
),
_link
(
link
)
{
}
...
...
@@ -141,12 +143,16 @@ public:
_globalCompletion
=
globalCompletion
;
}
QHash
<
QString
,
const
Interpreter
::
Value
*>
operator
()(
const
Interpreter
::
Value
*
value
,
bool
lookAtScope
=
false
)
QHash
<
QString
,
const
Interpreter
::
Value
*>
operator
()(
bool
lookAtScope
=
false
)
{
_processed
.
clear
();
_properties
.
clear
();
enumerateProperties
(
value
,
lookAtScope
);
if
(
!
lookAtScope
)
{
enumerateProperties
(
_link
->
scopeChain
().
first
());
}
else
{
foreach
(
const
Interpreter
::
ObjectValue
*
scope
,
_link
->
scopeChain
())
enumerateProperties
(
scope
);
}
return
_properties
;
}
...
...
@@ -183,25 +189,22 @@ private:
return
true
;
}
void
enumerateProperties
(
const
Interpreter
::
Value
*
value
,
bool
lookAtScope
)
void
enumerateProperties
(
const
Interpreter
::
Value
*
value
)
{
if
(
!
value
)
return
;
else
if
(
const
Interpreter
::
ObjectValue
*
object
=
value
->
asObjectValue
())
{
enumerateProperties
(
object
,
lookAtScope
);
enumerateProperties
(
object
);
}
}
void
enumerateProperties
(
const
Interpreter
::
ObjectValue
*
object
,
bool
lookAtScope
)
void
enumerateProperties
(
const
Interpreter
::
ObjectValue
*
object
)
{
if
(
!
object
||
_processed
.
contains
(
object
))
return
;
_processed
.
insert
(
object
);
enumerateProperties
(
object
->
prototype
(),
/* lookAtScope = */
false
);
if
(
lookAtScope
)
enumerateProperties
(
object
->
scope
(),
/* lookAtScope = */
true
);
enumerateProperties
(
object
->
prototype
());
object
->
processMembers
(
this
);
}
...
...
@@ -631,13 +634,11 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
Interpreter
::
Engine
interp
;
// Set up the current scope chain.
Interpreter
::
ObjectValue
*
scope
=
interp
.
globalObject
();
Link
link
(
document
,
snapshot
,
&
interp
);
if
(
document
)
{
AST
::
Node
*
declaringMember
=
semanticInfo
.
declaringMember
(
editor
->
position
());
scope
=
link
.
scopeChainAt
(
document
,
declaringMember
);
}
AST
::
Node
*
declaringMember
=
semanticInfo
.
declaringMember
(
editor
->
position
());
link
.
scopeChainAt
(
document
,
declaringMember
);
Link
::
ScopeChain
scope
=
link
.
scopeChain
();
// Search for the operator that triggered the completion.
QChar
completionOperator
;
...
...
@@ -647,9 +648,9 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
if
(
completionOperator
.
isSpace
()
||
completionOperator
.
isNull
()
||
isDelimiter
(
completionOperator
)
||
(
completionOperator
==
QLatin1Char
(
'('
)
&&
m_startPosition
!=
editor
->
position
()))
{
// It's a global completion.
EnumerateProperties
enumerateProperties
;
EnumerateProperties
enumerateProperties
(
&
link
)
;
enumerateProperties
.
setGlobalCompletion
(
true
);
QHashIterator
<
QString
,
const
Interpreter
::
Value
*>
it
(
enumerateProperties
(
scope
,
/* lookAtScope = */
true
));
QHashIterator
<
QString
,
const
Interpreter
::
Value
*>
it
(
enumerateProperties
(
/* lookAtScope = */
true
));
while
(
it
.
hasNext
())
{
it
.
next
();
...
...
@@ -670,15 +671,15 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
//qDebug() << "expression:" << expression;
if
(
expression
!=
0
)
{
Check
evaluate
(
&
interp
,
link
.
context
()
);
Check
evaluate
(
&
link
);
// Evaluate the expression under cursor.
const
Interpreter
::
Value
*
value
=
interp
.
convertToObject
(
evaluate
(
expression
,
scope
));
const
Interpreter
::
Value
*
value
=
interp
.
convertToObject
(
evaluate
(
expression
));
//qDebug() << "type:" << interp.typeId(value);
if
(
value
&&
completionOperator
==
QLatin1Char
(
'.'
))
{
// member completion
EnumerateProperties
enumerateProperties
;
QHashIterator
<
QString
,
const
Interpreter
::
Value
*>
it
(
enumerateProperties
(
value
));
EnumerateProperties
enumerateProperties
(
&
link
)
;
QHashIterator
<
QString
,
const
Interpreter
::
Value
*>
it
(
enumerateProperties
());
while
(
it
.
hasNext
())
{
it
.
next
();
...
...
src/plugins/qmljseditor/qmlhoverhandler.cpp
View file @
49c43aaa
...
...
@@ -173,10 +173,10 @@ void QmlHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
Interpreter
::
Engine
interp
;
Link
link
(
qmlDocument
,
snapshot
,
&
interp
);
const
Interpreter
::
ObjectValue
*
scope
=
link
.
scopeChainAt
(
qmlDocument
,
declaringMember
);
link
.
scopeChainAt
(
qmlDocument
,
declaringMember
);
Check
check
(
&
interp
,
link
.
context
()
);
const
Interpreter
::
Value
*
value
=
check
(
node
,
scope
);
Check
check
(
&
link
);
const
Interpreter
::
Value
*
value
=
check
(
node
);
QStringList
baseClasses
;
m_toolTip
=
prettyPrint
(
value
,
&
interp
,
&
baseClasses
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment