src/declarative/qml/qdeclarativescriptparser.cpp
changeset 37 758a864f9613
parent 33 3e2da88830cd
equal deleted inserted replaced
36:ef0373b55136 37:758a864f9613
   385     if (node->fileName) {
   385     if (node->fileName) {
   386         uri = node->fileName->asString();
   386         uri = node->fileName->asString();
   387 
   387 
   388         if (uri.endsWith(QLatin1String(".js"))) {
   388         if (uri.endsWith(QLatin1String(".js"))) {
   389             import.type = QDeclarativeScriptParser::Import::Script;
   389             import.type = QDeclarativeScriptParser::Import::Script;
   390             _parser->_refUrls << QUrl(uri);
       
   391         } else {
   390         } else {
   392             import.type = QDeclarativeScriptParser::Import::File;
   391             import.type = QDeclarativeScriptParser::Import::File;
   393         }
   392         }
   394     } else {
   393     } else {
   395         import.type = QDeclarativeScriptParser::Import::Library;
   394         import.type = QDeclarativeScriptParser::Import::Library;
   541 
   540 
   542         if (!typeFound && memberType.at(0).isUpper()) {
   541         if (!typeFound && memberType.at(0).isUpper()) {
   543             QString typemodifier;
   542             QString typemodifier;
   544             if(node->typeModifier)
   543             if(node->typeModifier)
   545                 typemodifier = node->typeModifier->asString();
   544                 typemodifier = node->typeModifier->asString();
   546             if (typemodifier == QString()) {
   545             if (typemodifier.isEmpty()) {
   547                 type = Object::DynamicProperty::Custom;
   546                 type = Object::DynamicProperty::Custom;
   548             } else if(typemodifier == QLatin1String("list")) {
   547             } else if(typemodifier == QLatin1String("list")) {
   549                 type = Object::DynamicProperty::CustomList;
   548                 type = Object::DynamicProperty::CustomList;
   550             } else {
   549             } else {
   551                 QDeclarativeError error;
   550                 QDeclarativeError error;
   758 
   757 
   759     // For the DOM, store the position of the T_LBRACKET upto the T_RBRACKET as the range:
   758     // For the DOM, store the position of the T_LBRACKET upto the T_RBRACKET as the range:
   760     prop->listValueRange.offset = node->lbracketToken.offset;
   759     prop->listValueRange.offset = node->lbracketToken.offset;
   761     prop->listValueRange.length = node->rbracketToken.offset + node->rbracketToken.length - node->lbracketToken.offset;
   760     prop->listValueRange.length = node->rbracketToken.offset + node->rbracketToken.length - node->lbracketToken.offset;
   762 
   761 
   763     // Store the positions of the comma token too, again for the DOM to be able to retreive it.
   762     // Store the positions of the comma token too, again for the DOM to be able to retrieve it.
   764     prop->listCommaPositions = collectCommas(node->members);
   763     prop->listCommaPositions = collectCommas(node->members);
   765 
   764 
   766     while (propertyCount--)
   765     while (propertyCount--)
   767         _stateStack.pop();
   766         _stateStack.pop();
   768 
   767 
   829 
   828 
   830     const QString fileName = url.toString();
   829     const QString fileName = url.toString();
   831     _scriptFile = fileName;
   830     _scriptFile = fileName;
   832 
   831 
   833     QTextStream stream(qmldata, QIODevice::ReadOnly);
   832     QTextStream stream(qmldata, QIODevice::ReadOnly);
       
   833 #ifndef QT_NO_TEXTCODEC
   834     stream.setCodec("UTF-8");
   834     stream.setCodec("UTF-8");
       
   835 #endif
   835     const QString code = stream.readAll();
   836     const QString code = stream.readAll();
   836 
   837 
   837     data = new QDeclarativeScriptParserJsASTData(fileName);
   838     data = new QDeclarativeScriptParserJsASTData(fileName);
   838 
   839 
   839     Lexer lexer(&data->engine);
   840     Lexer lexer(&data->engine);
   874 QList<QDeclarativeScriptParser::TypeReference*> QDeclarativeScriptParser::referencedTypes() const
   875 QList<QDeclarativeScriptParser::TypeReference*> QDeclarativeScriptParser::referencedTypes() const
   875 {
   876 {
   876     return _refTypes;
   877     return _refTypes;
   877 }
   878 }
   878 
   879 
   879 QList<QUrl> QDeclarativeScriptParser::referencedResources() const
       
   880 {
       
   881     return _refUrls;
       
   882 }
       
   883 
       
   884 Object *QDeclarativeScriptParser::tree() const
   880 Object *QDeclarativeScriptParser::tree() const
   885 {
   881 {
   886     return root;
   882     return root;
   887 }
   883 }
   888 
   884 
   956         }
   952         }
   957     }
   953     }
   958     return rv;
   954     return rv;
   959 }
   955 }
   960 
   956 
       
   957 #define CHECK_LINE if(l.currentLineNo() != startLine) return rv;
       
   958 #define CHECK_TOKEN(t) if (token != QDeclarativeJSGrammar:: t) return rv;
       
   959 
       
   960 static const int uriTokens[] = {
       
   961     QDeclarativeJSGrammar::T_IDENTIFIER, 
       
   962     QDeclarativeJSGrammar::T_PROPERTY, 
       
   963     QDeclarativeJSGrammar::T_SIGNAL, 
       
   964     QDeclarativeJSGrammar::T_READONLY, 
       
   965     QDeclarativeJSGrammar::T_ON, 
       
   966     QDeclarativeJSGrammar::T_BREAK, 
       
   967     QDeclarativeJSGrammar::T_CASE, 
       
   968     QDeclarativeJSGrammar::T_CATCH, 
       
   969     QDeclarativeJSGrammar::T_CONTINUE, 
       
   970     QDeclarativeJSGrammar::T_DEFAULT, 
       
   971     QDeclarativeJSGrammar::T_DELETE, 
       
   972     QDeclarativeJSGrammar::T_DO, 
       
   973     QDeclarativeJSGrammar::T_ELSE, 
       
   974     QDeclarativeJSGrammar::T_FALSE, 
       
   975     QDeclarativeJSGrammar::T_FINALLY, 
       
   976     QDeclarativeJSGrammar::T_FOR, 
       
   977     QDeclarativeJSGrammar::T_FUNCTION, 
       
   978     QDeclarativeJSGrammar::T_IF, 
       
   979     QDeclarativeJSGrammar::T_IN, 
       
   980     QDeclarativeJSGrammar::T_INSTANCEOF, 
       
   981     QDeclarativeJSGrammar::T_NEW, 
       
   982     QDeclarativeJSGrammar::T_NULL, 
       
   983     QDeclarativeJSGrammar::T_RETURN, 
       
   984     QDeclarativeJSGrammar::T_SWITCH, 
       
   985     QDeclarativeJSGrammar::T_THIS, 
       
   986     QDeclarativeJSGrammar::T_THROW, 
       
   987     QDeclarativeJSGrammar::T_TRUE, 
       
   988     QDeclarativeJSGrammar::T_TRY, 
       
   989     QDeclarativeJSGrammar::T_TYPEOF, 
       
   990     QDeclarativeJSGrammar::T_VAR, 
       
   991     QDeclarativeJSGrammar::T_VOID, 
       
   992     QDeclarativeJSGrammar::T_WHILE, 
       
   993     QDeclarativeJSGrammar::T_CONST, 
       
   994     QDeclarativeJSGrammar::T_DEBUGGER, 
       
   995     QDeclarativeJSGrammar::T_RESERVED_WORD, 
       
   996     QDeclarativeJSGrammar::T_WITH, 
       
   997 
       
   998     QDeclarativeJSGrammar::EOF_SYMBOL
       
   999 };
       
  1000 static inline bool isUriToken(int token)
       
  1001 {
       
  1002     const int *current = uriTokens;
       
  1003     while (*current != QDeclarativeJSGrammar::EOF_SYMBOL) {
       
  1004         if (*current == token)
       
  1005             return true;
       
  1006         ++current;
       
  1007     }
       
  1008     return false;
       
  1009 }
       
  1010 
       
  1011 QDeclarativeScriptParser::JavaScriptMetaData QDeclarativeScriptParser::extractMetaData(QString &script)
       
  1012 {
       
  1013     JavaScriptMetaData rv;
       
  1014 
       
  1015     QDeclarativeParser::Object::ScriptBlock::Pragmas &pragmas = rv.pragmas;
       
  1016 
       
  1017     const QString pragma(QLatin1String("pragma"));
       
  1018     const QString js(QLatin1String(".js"));
       
  1019     const QString library(QLatin1String("library"));
       
  1020 
       
  1021     QDeclarativeJS::Lexer l(0);
       
  1022     l.setCode(script, 0);
       
  1023 
       
  1024     int token = l.lex();
       
  1025 
       
  1026     while (true) {
       
  1027         if (token != QDeclarativeJSGrammar::T_DOT)
       
  1028             return rv;
       
  1029 
       
  1030         int startOffset = l.tokenOffset();
       
  1031         int startLine = l.currentLineNo();
       
  1032 
       
  1033         token = l.lex();
       
  1034 
       
  1035         CHECK_LINE;
       
  1036 
       
  1037         if (token == QDeclarativeJSGrammar::T_IMPORT) {
       
  1038 
       
  1039             // .import <URI> <Version> as <Identifier>
       
  1040             // .import <file.js> as <Identifier>
       
  1041 
       
  1042             token = l.lex();
       
  1043 
       
  1044             CHECK_LINE;
       
  1045 
       
  1046             if (token == QDeclarativeJSGrammar::T_STRING_LITERAL) {
       
  1047 
       
  1048                 QString file(l.characterBuffer(), l.characterCount());
       
  1049                 if (!file.endsWith(js))
       
  1050                     return rv;
       
  1051 
       
  1052                 token = l.lex();
       
  1053 
       
  1054                 CHECK_TOKEN(T_AS);
       
  1055                 CHECK_LINE;
       
  1056 
       
  1057                 token = l.lex();
       
  1058 
       
  1059                 CHECK_TOKEN(T_IDENTIFIER);
       
  1060                 CHECK_LINE;
       
  1061 
       
  1062                 int endOffset = l.tokenLength() + l.tokenOffset();
       
  1063 
       
  1064                 QString importId = script.mid(l.tokenOffset(), l.tokenLength());
       
  1065 
       
  1066                 if (!importId.at(0).isUpper())
       
  1067                     return rv;
       
  1068 
       
  1069                 token = l.lex();
       
  1070                 if (l.currentLineNo() == startLine)
       
  1071                     return rv;
       
  1072 
       
  1073                 replaceWithSpace(script, startOffset, endOffset - startOffset);
       
  1074 
       
  1075                 Import import;
       
  1076                 import.type = Import::Script;
       
  1077                 import.uri = file;
       
  1078                 import.qualifier = importId;
       
  1079 
       
  1080                 rv.imports << import;
       
  1081 
       
  1082             } else {
       
  1083                 // URI
       
  1084                 QString uri;
       
  1085                 QString version;
       
  1086 
       
  1087                 while (true) {
       
  1088                     if (!isUriToken(token))
       
  1089                         return rv;
       
  1090 
       
  1091                     uri.append(QString(l.characterBuffer(), l.characterCount()));
       
  1092 
       
  1093                     token = l.lex();
       
  1094                     CHECK_LINE;
       
  1095                     if (token != QDeclarativeJSGrammar::T_DOT)
       
  1096                         break;
       
  1097 
       
  1098                     uri.append(QLatin1Char('.'));
       
  1099 
       
  1100                     token = l.lex();
       
  1101                     CHECK_LINE;
       
  1102                 }
       
  1103 
       
  1104                 CHECK_TOKEN(T_NUMERIC_LITERAL);
       
  1105                 version = script.mid(l.tokenOffset(), l.tokenLength());
       
  1106 
       
  1107                 token = l.lex();
       
  1108 
       
  1109                 CHECK_TOKEN(T_AS);
       
  1110                 CHECK_LINE;
       
  1111 
       
  1112                 token = l.lex();
       
  1113 
       
  1114                 CHECK_TOKEN(T_IDENTIFIER);
       
  1115                 CHECK_LINE;
       
  1116 
       
  1117                 int endOffset = l.tokenLength() + l.tokenOffset();
       
  1118 
       
  1119                 QString importId = script.mid(l.tokenOffset(), l.tokenLength());
       
  1120 
       
  1121                 if (!importId.at(0).isUpper())
       
  1122                     return rv;
       
  1123 
       
  1124                 token = l.lex();
       
  1125                 if (l.currentLineNo() == startLine)
       
  1126                     return rv;
       
  1127 
       
  1128                 replaceWithSpace(script, startOffset, endOffset - startOffset);
       
  1129 
       
  1130                 Import import;
       
  1131                 import.type = Import::Library;
       
  1132                 import.uri = uri;
       
  1133                 import.version = version;
       
  1134                 import.qualifier = importId;
       
  1135 
       
  1136                 rv.imports << import;
       
  1137             }
       
  1138 
       
  1139         } else if (token == QDeclarativeJSGrammar::T_IDENTIFIER &&
       
  1140                    script.mid(l.tokenOffset(), l.tokenLength()) == pragma) {
       
  1141 
       
  1142             token = l.lex();
       
  1143 
       
  1144             CHECK_TOKEN(T_IDENTIFIER);
       
  1145             CHECK_LINE;
       
  1146 
       
  1147             QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
       
  1148             int endOffset = l.tokenLength() + l.tokenOffset();
       
  1149 
       
  1150             if (pragmaValue == QLatin1String("library")) {
       
  1151                 pragmas |= QDeclarativeParser::Object::ScriptBlock::Shared;
       
  1152                 replaceWithSpace(script, startOffset, endOffset - startOffset);
       
  1153             } else {
       
  1154                 return rv;
       
  1155             }
       
  1156 
       
  1157             token = l.lex();
       
  1158             if (l.currentLineNo() == startLine)
       
  1159                 return rv;
       
  1160 
       
  1161         } else {
       
  1162             return rv;
       
  1163         }
       
  1164     }
       
  1165     return rv;
       
  1166 }
       
  1167 
   961 void QDeclarativeScriptParser::clear()
  1168 void QDeclarativeScriptParser::clear()
   962 {
  1169 {
   963     if (root) {
  1170     if (root) {
   964         root->release();
  1171         root->release();
   965         root = 0;
  1172         root = 0;