Changeset View
Changeset View
Standalone View
Standalone View
src/qmljsc/ir/file.cpp
Show All 22 Lines | |||||
23 | #include "module.h" | 23 | #include "module.h" | ||
24 | #include "../utils/error.h" | 24 | #include "../utils/error.h" | ||
25 | #include "../compiler.h" | 25 | #include "../compiler.h" | ||
26 | #include "visitor.h" | 26 | #include "visitor.h" | ||
27 | 27 | | |||
28 | using namespace QmlJSc; | 28 | using namespace QmlJSc; | ||
29 | using namespace QmlJSc::IR; | 29 | using namespace QmlJSc::IR; | ||
30 | 30 | | |||
31 | bool File::ModuleData::operator==(const File::ModuleData& other) const | 31 | Import::Import(const QUrl& url, const QString& localPrefix) | ||
32 | : m_filePath(url) | ||||
33 | , m_module(0) | ||||
34 | , m_localPrefix(localPrefix) | ||||
32 | { | 35 | { | ||
33 | return module == other.module; | 36 | m_importType = FileImport; //TODO: Decide between file and directory import | ||
37 | } | ||||
38 | | ||||
39 | Import::Import(Module* module, const QString& localPrefix) | ||||
40 | : m_importType(ModuleImport) | ||||
41 | , m_module(module) | ||||
42 | , m_localPrefix(localPrefix) | ||||
43 | { | ||||
44 | } | ||||
45 | | ||||
46 | QmlJSc::IR::Import::Import() | ||||
47 | : m_importType(Invalid) | ||||
48 | , m_module(0) | ||||
49 | { | ||||
50 | } | ||||
51 | | ||||
52 | QmlJSc::IR::Import::Import(const QmlJSc::IR::Import& other) | ||||
53 | : m_importType(other.importType()) | ||||
54 | , m_module(other.module()) | ||||
55 | , m_filePath(other.filePath()) | ||||
56 | , m_localPrefix(other.localPrefix()) | ||||
57 | { | ||||
58 | } | ||||
59 | | ||||
60 | bool QmlJSc::IR::Import::operator==(const QmlJSc::IR::Import& other) const | ||||
61 | { | ||||
62 | return m_importType == other.importType() | ||||
63 | && m_module == other.module() | ||||
64 | && m_filePath == other.filePath() | ||||
65 | && m_importType == other.importType(); | ||||
66 | } | ||||
67 | | ||||
68 | void Import::accept(Visitor* visitor) | ||||
69 | { | ||||
70 | visitor->visit(this); | ||||
71 | visitor->endVisit(this); | ||||
72 | } | ||||
73 | | ||||
74 | Node::Kind Import::kind() const | ||||
75 | { | ||||
76 | return Kind_Import; | ||||
77 | } | ||||
78 | | ||||
79 | Module * Import::module() const | ||||
80 | { | ||||
81 | return m_module; | ||||
82 | } | ||||
83 | | ||||
84 | QUrl Import::filePath() const | ||||
85 | { | ||||
86 | return m_filePath; | ||||
87 | } | ||||
88 | | ||||
89 | Import::ImportType Import::importType() const | ||||
90 | { | ||||
91 | return m_importType; | ||||
92 | } | ||||
93 | | ||||
94 | const QString &Import::localPrefix() const | ||||
95 | { | ||||
96 | return m_localPrefix; | ||||
34 | } | 97 | } | ||
35 | 98 | | |||
36 | File::File() | 99 | File::File() | ||
37 | : m_prefix('A' - 1) // we want the prefix to be 'A' after the first preincrement | 100 | : m_prefix('A' - 1) // we want the prefix to be 'A' after the first preincrement | ||
38 | { | 101 | { | ||
39 | } | 102 | } | ||
40 | 103 | | |||
104 | File::File(std::initializer_list<Import> imports, ObjectSpec *rootObject) | ||||
105 | : m_importedModules(imports) | ||||
106 | , m_prefix('A' - 1) | ||||
107 | , m_rootObject(rootObject) | ||||
108 | { | ||||
109 | } | ||||
110 | | ||||
41 | File::~File() | 111 | File::~File() | ||
42 | { | 112 | { | ||
43 | } | 113 | } | ||
44 | 114 | | |||
45 | Node::Kind File::kind() const | 115 | Node::Kind File::kind() const | ||
46 | { | 116 | { | ||
47 | return Node::Kind_File; | 117 | return Node::Kind_File; | ||
48 | } | 118 | } | ||
49 | 119 | | |||
50 | void File::addModule(Module *module, const QString &prefix) | 120 | void File::addModule(Module *module, const QString &prefix) | ||
51 | { | 121 | { | ||
52 | if (m_importedModules.contains({ module, QString() })) | 122 | if (m_importedModules.contains({ module })) | ||
53 | return; | 123 | return; | ||
54 | 124 | | |||
55 | ModuleData moduleData; | 125 | Import import(module, prefix.isEmpty() ? ++m_prefix : prefix); | ||
56 | moduleData.module = module; | 126 | m_importedModules.append(import); | ||
57 | if (!prefix.isEmpty()) { | | |||
58 | moduleData.localPrefix = prefix; | | |||
59 | } else { | | |||
60 | moduleData.localPrefix = ++m_prefix; | | |||
61 | } | | |||
62 | m_importedModules.append(moduleData); | | |||
63 | } | 127 | } | ||
64 | 128 | | |||
65 | Type *File::type(const QString &typeName) const | 129 | Type *File::type(const QString &typeName) const | ||
66 | { | 130 | { | ||
67 | if (Type *builtinType = IR::BuiltinTypes::type(typeName)) { | 131 | if (Type *builtinType = IR::BuiltinTypes::type(typeName)) { | ||
68 | return builtinType; | 132 | return builtinType; | ||
69 | } | 133 | } | ||
70 | const ModuleData *data = moduleForType(typeName); | 134 | const Import *data = moduleForType(typeName); | ||
71 | if (data && data->module) | 135 | if (data && data->module()) | ||
72 | return data->module->type(typeName); | 136 | return data->module()->type(typeName); | ||
73 | 137 | | |||
74 | return 0; | 138 | return 0; | ||
75 | } | 139 | } | ||
76 | 140 | | |||
77 | QString File::fullyQualifiedName(const QString &typeName) | 141 | QString File::fullyQualifiedName(const QString &typeName) | ||
78 | { | 142 | { | ||
79 | return QStringLiteral("%1.%2").arg(moduleForType(typeName)->localPrefix, typeName); | 143 | return QStringLiteral("%1.%2").arg(moduleForType(typeName)->localPrefix(), typeName); | ||
80 | } | 144 | } | ||
81 | 145 | | |||
82 | ObjectSpec *File::rootObject() const | 146 | ObjectSpec *File::rootObject() const | ||
83 | { | 147 | { | ||
84 | return m_rootObject; | 148 | return m_rootObject; | ||
85 | } | 149 | } | ||
86 | 150 | | |||
87 | void File::setRootObject(ObjectSpec *rootObject) | 151 | void File::setRootObject(ObjectSpec *rootObject) | ||
88 | { | 152 | { | ||
89 | m_rootObject = rootObject; | 153 | m_rootObject = rootObject; | ||
90 | } | 154 | } | ||
91 | 155 | | |||
92 | const File::ModuleData *File::moduleForType(const QString &typeName) const | 156 | const Import *File::moduleForType(const QString &typeName) const | ||
93 | { | 157 | { | ||
94 | Type *foundType = 0; | 158 | Type *foundType = 0; | ||
95 | const ModuleData *moduleData = 0; | 159 | const Import *moduleData = 0; | ||
96 | foreach (const ModuleData &data, m_importedModules) { | 160 | foreach (const Import &data, m_importedModules) { | ||
97 | if (Type * type = data.module->type(typeName)) { | 161 | if (Type * type = data.module()->type(typeName)) { | ||
98 | if (foundType) { | 162 | if (foundType) { | ||
99 | throw Error( | 163 | throw Error( | ||
100 | QmlJSc::Error::SymbolLookupError, | 164 | QmlJSc::Error::SymbolLookupError, | ||
101 | QString("Ambigious type name. Type %1 was defined by module %2 and %3.") | 165 | QString("Ambigious type name. Type %1 was defined by module %2 and %3.") | ||
102 | .arg(typeName, moduleData->module->name(), data.module->name()) | 166 | .arg(typeName, moduleData->module()->name(), data.module()->name()) | ||
103 | ); | 167 | ); | ||
104 | return 0; | 168 | return 0; | ||
105 | } else { | 169 | } else { | ||
106 | foundType = type; | 170 | foundType = type; | ||
107 | moduleData = &data; | 171 | moduleData = &data; | ||
108 | } | 172 | } | ||
109 | } | 173 | } | ||
110 | } | 174 | } | ||
111 | return moduleData; | 175 | return moduleData; | ||
112 | } | 176 | } | ||
113 | 177 | | |||
114 | void QmlJSc::IR::File::accept(QmlJSc::IR::Visitor* visitor) | 178 | void QmlJSc::IR::File::accept(QmlJSc::IR::Visitor* visitor) | ||
115 | { | 179 | { | ||
116 | visitor->visit(this); | 180 | visitor->visit(this); | ||
181 | for (Import &import : m_importedModules) { | ||||
182 | import.accept(visitor); | ||||
183 | } | ||||
117 | m_rootObject->accept(visitor); | 184 | m_rootObject->accept(visitor); | ||
118 | visitor->endVisit(this); | 185 | visitor->endVisit(this); | ||
119 | } | 186 | } | ||
120 | 187 | | |||
121 | const QVector<File::ModuleData> &File::importedModules() const | 188 | const QVector<Import> &File::importedModules() const | ||
122 | { | 189 | { | ||
123 | return m_importedModules; | 190 | return m_importedModules; | ||
124 | } | 191 | } |