CE Source.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. /******************************************************************************/
  2. namespace Edit{
  3. /******************************************************************************/
  4. enum ERROR_TYPE
  5. {
  6. EE_ERR_NONE ,
  7. EE_ERR_FILE_NOT_FOUND ,
  8. EE_ERR_FILE_INVALID ,
  9. EE_ERR_FILE_READ_ERROR ,
  10. EE_ERR_ELM_NOT_FOUND ,
  11. EE_ERR_ELM_NOT_CODE ,
  12. EE_ERR_ELM_NOT_DOWNLOADED,
  13. };
  14. #if EE_PRIVATE
  15. #define CODE_EXT "es|c|cpp|h|cs|cc|cxx|m|mm|java|txt|xml|htm|html|php|mk"
  16. /******************************************************************************/
  17. struct LineMode // Line information, which can start with being inside comment or not (2 modes)
  18. {
  19. Bool starts_with_comment, ends_with_comment, preproc, starts_with_preproc, ends_with_preproc, starts_with_macro_param;
  20. Memc<TOKEN_TYPE> type; // type of character
  21. Memc<Token > tokens;
  22. void resetTokens() {REPAO(tokens).reset();}
  23. void clear( ) {type.clear(); tokens.clear();}
  24. TOKEN_TYPE Type (Int i)C {return InRange(i, type) ? TOKEN_TYPE(type[i]) : TOKEN_NONE;}
  25. void setTokens(Line &line);
  26. void resetType(Line &line);
  27. void setType(Line &line, Bool starts_with_comment, Bool starts_with_preproc);
  28. Bool save(File &f, StrLibrary &sl, C Str &text)C;
  29. Bool load(File &f, StrLibrary &sl, C Str &text, Line &line, Str &temp);
  30. LineMode() {starts_with_comment=ends_with_comment=preproc=starts_with_preproc=ends_with_preproc=starts_with_macro_param=false;}
  31. };
  32. /******************************************************************************/
  33. struct Line : Str, Text, LineMode
  34. {
  35. #if !WINDOWS
  36. typedef Text super;
  37. #endif
  38. Bool changed, text_valid, tokens_preproc_use, tokens_preproc_condition_unavailable;
  39. Int line; // original line index
  40. UID id;
  41. Source *source;
  42. LineMode comment_mode;
  43. Memc<Token> tokens_preproc;
  44. Memc<Token>& Tokens() {return tokens_preproc_use ? tokens_preproc : tokens;}
  45. C Memc<Token>& Tokens()C {return tokens_preproc_use ? tokens_preproc : tokens;}
  46. ~Line();
  47. Line() {changed=true; text_valid=false; tokens_preproc_use=tokens_preproc_condition_unavailable=false; line=-1; id.randomize(); source=null;}
  48. void resetTokens ( ) {LineMode::resetTokens(); comment_mode.resetTokens(); REPAO(tokens_preproc).reset();}
  49. void resetPreproc(Bool inside_macro_param) {text_valid=false; starts_with_macro_param=inside_macro_param; tokens_preproc_use=inside_macro_param; tokens_preproc.clear(); REPAO(tokens).macro=false;}
  50. void preprocChanged();
  51. void clear ( ) {Str::clear(); LineMode::clear(); comment_mode.clear(); tokens_preproc.clear(); changed=true;}
  52. void operator=(C Str &src) {clear(); Str &s=T; s=src;}
  53. Char first ()C {return Str::first();}
  54. Char last ()C {return Str::last ();}
  55. CChar* operator()()C {return Str::operator()();}
  56. Line& clip (Int length ) {Str::clip(length); changed=true; return T;}
  57. Line& clipSpaces( ) {for(; last()==' '; )removeLast(); changed=true; return T;}
  58. Line& removeLast( ) {return remove(length()-1);}
  59. Line& remove (Int i, Int num=1)
  60. {
  61. if(num>0)
  62. {
  63. Str::remove (i, num);
  64. LineMode::type.removeNum(i, num, true);
  65. comment_mode. type.removeNum(i, num, true);
  66. changed=true;
  67. }
  68. return T;
  69. }
  70. Line& insert(Int i, C Str &text, TOKEN_TYPE type=TOKEN_NONE)
  71. {
  72. if(text.is())
  73. {
  74. Str::insert(i, text);
  75. REPAD(n, text)
  76. {
  77. LineMode::type.NewAt(i)=type;
  78. comment_mode. type.NewAt(i)=type;
  79. }
  80. changed=true;
  81. }
  82. return T;
  83. }
  84. Line& append(C Str &text, TOKEN_TYPE type=TOKEN_NONE) {return insert(length(), text, type);}
  85. Line& operator+=(Char8 c) {return append(c);}
  86. Line& operator+=(Char c) {return append(c);}
  87. Line& operator+=(CChar8 *t) {return append(t);}
  88. Line& operator+=(CChar *t) {return append(t);}
  89. Line& setChar(Int i, Char c, TOKEN_TYPE type=TOKEN_NONE)
  90. {
  91. if(InRange(i, T) && c)
  92. {
  93. Str::setChar(i, c);
  94. LineMode::type(i)=type;
  95. comment_mode. type(i)=type;
  96. changed=true;
  97. }
  98. return T;
  99. }
  100. void resetType();
  101. void setType(Bool starts_with_comment, Bool starts_with_preproc);
  102. void setRect(Int i );
  103. void setGui (Int i, GuiObj &parent);
  104. Int end ( ) { REPA( T)if(T[i]!=' ') return i+1; return 0;}
  105. Int start ( ) {FREPA( T)if(T[i]!=' ') return i; return 0;}
  106. Bool empty ( ) { REPA( T)if(T[i]!=' ') return false; return true;}
  107. Char chrBefore(Int x, Int *pos=null) { REP (Min(length(), x) )if(T[i]!=' '){if(pos)*pos=i; return T[i];} if(pos)*pos=-1; return 0;}
  108. Char chrNext (Int x, Int *pos=null) {for(Int i=x; i<length(); i++)if(T[i]!=' '){if(pos)*pos=i; return T[i];} if(pos)*pos=-1; return 0;}
  109. Char chrFirst ( Int *pos=null) {return chrNext(0, pos);}
  110. Int wordStart(Int x );
  111. Int wordEnd (Int x );
  112. Int wordBegin(Int x );
  113. Str textTokens()C;
  114. Str textCode () ;
  115. virtual void draw(C GuiPC &gpc);
  116. Bool saveData(File &f)C;
  117. Bool loadData(File &f);
  118. Bool save(File &f, StrLibrary &sl)C;
  119. Bool load(File &f, StrLibrary &sl, Int line, Source &source, Str &temp);
  120. };
  121. /******************************************************************************/
  122. struct PrepCond // Preprocess Conditional (#if, #ifdef, #ifndef, #elif, #else, #endif)
  123. {
  124. Bool can_enter , // if can enter a "#elif" or "#else" condition
  125. currently_valid; // if currently is inside a valid condition
  126. void set(Bool can_enter, Bool currently_valid) {T.can_enter=can_enter; T.currently_valid=currently_valid;}
  127. };
  128. /******************************************************************************/
  129. const_mem_addr STRUCT(Source , Region)
  130. //{
  131. enum UNDO_TYPE
  132. {
  133. DEFAULT ,
  134. INS_CHR ,
  135. DEL_CHR ,
  136. INS_CHRS,
  137. };
  138. struct UndoChange : _Undo::Change
  139. {
  140. File data;
  141. VecI2 cur, sel;
  142. DateTime modify_time;
  143. virtual void create(Ptr source);
  144. virtual void apply (Ptr source);
  145. };
  146. struct Suggestion
  147. {
  148. Bool is_macro;
  149. Byte macro_params; // 0-no brackets "X", 1-has brackets but no params "X()", 2-has brackets and params "X(..)"
  150. Int priority;
  151. Str text, display, macro_def;
  152. SymbolPtr symbol;
  153. UID elm_id;
  154. ImagePtr icon;
  155. mutable Int _order;
  156. Int order()C;
  157. void set(Int priority, C Str &text, Symbol &symbol );
  158. void set(Int priority, C Macro &macro );
  159. void set(Int priority, C Str &text, C UID &id, C ImagePtr &icon); // project element
  160. };
  161. struct ViewLine : CodeLine, Text
  162. {
  163. #if !WINDOWS
  164. typedef Text super;
  165. #endif
  166. Bool text_valid;
  167. Source *source;
  168. Int line ( )C {return lines.y;} // get original line index (use Y because it can be -1)
  169. Int findCol(Int col)C {return findPos(VecI2(col, line()));}
  170. ViewLine( ) {text_valid=false; source=null;}
  171. ViewLine(C ViewLine &line)
  172. {
  173. SCAST(CodeLine, T)=SCAST(C CodeLine, line);
  174. text_valid=line.text_valid;
  175. source =line.source;
  176. }
  177. void setRect(Int i);
  178. Str textCode();
  179. virtual void draw(C GuiPC &gpc);
  180. };
  181. SourceLoc loc; // how this source is stored
  182. Bool active, was_active, header, ee_header, // if source is included in current build and symbols generation
  183. cpp, // if source is C++ style file (not .es)
  184. opened, Const;
  185. Int highlight_line, recursive, parse_count, preproc_line_changed;
  186. Flt highlight_time;
  187. Str cur_text;
  188. VecI2 cur, sel, sel_temp;
  189. Vec2 lc_offset; // line column offset
  190. Undo<UndoChange> undos;
  191. Int undo_original_state; // index of UndoChange that is currently saved on the disk
  192. VecI2 suggestions_pos;
  193. Region suggestions_region;
  194. List<Suggestion> suggestions_list;
  195. Memc<Suggestion> suggestions;
  196. TextLine suggestions_textline; // for project elements
  197. DateTime modify_time;
  198. Bool view_comments, view_funcs, view_func_bodies, view_private_members;
  199. Memc<ViewLine > view_lines; //
  200. Memx<Line > lines; // Memx because of Gui Text inside which requires const_mem_addr
  201. Memc<SymbolDef > symbols; // symbol definitions
  202. Memc<SymbolDecl> decls; // symbol forward declarations
  203. Memc<Token* > tokens;
  204. WindowIO *win_io_save; // WinIO used only for saving
  205. Symbol *lit_symbol; // highlight occurences of this symbol when drawing
  206. Str lit_symbol_cpp_name;
  207. ~Source();
  208. Source();
  209. // io
  210. Bool save(File &f, StrLibrary &sl)C;
  211. Bool load(File &f, StrLibrary &sl, Str &temp);
  212. ERROR_TYPE load ();
  213. void reload ();
  214. ERROR_TYPE load (C SourceLoc &loc );
  215. Bool save (C SourceLoc &loc );
  216. Bool saveTxt(C Str &name);
  217. void save ();
  218. Bool overwrite();
  219. // get
  220. Bool hasUnicode ()C;
  221. Bool used ()C;
  222. Bool modified ()C;
  223. Bool hasFocus (GuiObj *go)C;
  224. Bool hasMsFocus ()C {return hasFocus(Gui.ms());}
  225. Bool hasKbFocus ()C;
  226. Bool isCurVisible()C;
  227. Token* getToken (Int token_index) {return InRange(token_index, tokens) ? tokens[token_index] : null;}
  228. Char operator[] (C VecI2 &pos )C {return InRange(pos.y, lines) ? lines[pos.y] [pos.x] : 0;}
  229. TOKEN_TYPE Type (C VecI2 &pos )C {return InRange(pos.y, lines) ? lines[pos.y].Type(pos.x) : TOKEN_NONE;}
  230. Bool lineValid (C VecI2 &pos )C {return InRange(pos.y, lines);}
  231. Bool posValid (C VecI2 &pos )C {return InRange(pos.y, lines) && InRange(pos.x, lines[pos.y]);}
  232. Vec2 posVisual (C VecI2 &pos )C;
  233. Bool insideRSTBrackets(C VecI2 &pos ) ; // if inside Round() Square[] Template<> Brackets
  234. Vec2 posCur (C Vec2 &pos )C; // convert screen position to cursor
  235. Vec2 offset ( )C; // get offset applied to code text
  236. Int findLine (C UID &id )C {REPA(lines)if(lines[i].id==id)return i; return -1;}
  237. Bool viewToReal(C VecI2 &view, VecI2 &real)C; // conversion is precise
  238. Int viewToReal( Int view )C; // conversion is precise
  239. Int realToView( Int real)C; // conversion is approximate
  240. VecI2 realToView( C VecI2 &real)C; // conversion is approximate
  241. Str textTokens()C;
  242. // operations
  243. void replacePath(C Str &src, C Str &dest);
  244. void setScroll();
  245. void setHideSlideBar();
  246. void curSel(VecI2 &min, VecI2 &max);
  247. VecI2& dec(VecI2 &p);
  248. VecI2& inc(VecI2 &p);
  249. // edit
  250. void startSel();
  251. void highlight(Int line, Bool immediate);
  252. void makeCurVisible(Bool center=false, Bool immediate=true);
  253. void curLeft ();
  254. void curRight ();
  255. void curUp ();
  256. void curDown ();
  257. void curLineBegin();
  258. void curLineEnd ();
  259. void selAll ();
  260. void selWord ();
  261. void curPrevWord();
  262. void curNextWord();
  263. void curPrevBracket();
  264. void curNextBracket();
  265. void curPrevLevelBracket();
  266. void curNextLevelBracket();
  267. void curPageUp ();
  268. void curPageDown();
  269. Int viewBeginPos();
  270. Int viewEndPos ();
  271. void curViewBegin();
  272. void curViewEnd ();
  273. void curDocBegin();
  274. void curDocEnd ();
  275. void curClip();
  276. void removeLine(Int i);
  277. void delSel(Bool set_undo=true, Bool clear_suggestions=true);
  278. void cut ();
  279. void copy ();
  280. void paste (C Str *text=null, Bool move_cur=true);
  281. void separator();
  282. void delForward();
  283. void delBack();
  284. void delWordForward();
  285. void delWordBack ();
  286. void makeCase(Bool upper);
  287. void forceCreateNextUndo();
  288. void delUndo();
  289. void setUndo(UNDO_TYPE undo_type=DEFAULT);
  290. void undoAsChange();
  291. void undo();
  292. void redo();
  293. Str asText()C;
  294. void fromText(C Str &data);
  295. // preprocessor
  296. /*Memc<Macro>& macrosForLine(Int y)
  297. {
  298. for(y--; InRange(y, lines); y--)if(lines[y].has_macros)return lines[y].macros; // find first previous line which has macro definitions
  299. return ProjectMacros; // if not found then use global macros
  300. }*/
  301. Token* previewNextToken(Int line_index, Int line_token_index);
  302. Token* getNextToken(Int &line_index, Int &line_token_index, Bool only_cur_line=false);
  303. struct TokenSource
  304. {
  305. Memc<Token> *tokens;
  306. Int token_index; // index in 'tokens'
  307. Source *source;
  308. Int *line_index,
  309. *line_token_index; // index in 'Line.tokens'
  310. Token* previewNext ();
  311. Token* next (Bool only_cur_line=false);
  312. void removeLastRead();
  313. TokenSource() {tokens=null; token_index=0; source=null; line_index=null; line_token_index=null;}
  314. };
  315. Int findMacro (Memc<Macro> &macros, BStr &macro, Mems<Bool> *macro_used=null);
  316. Int findMacroToReplace(Memc<Macro> &macros, BStr &macro, TokenSource &ts, Mems<Bool> *macro_used=null);
  317. Int findMacroToReplace(Memc<Macro> &macros, BStr &macro, Int line_index, Int line_token_index);
  318. struct MacroParam
  319. {
  320. Memc<Token> tokens;
  321. };
  322. void replaceMacro(Int macro_index, Memc<Macro> &macros, TokenSource &ts, Mems<Bool> &macro_used, Int depth, Int col, Line &line);
  323. Bool getConditionalValue(Memc<Token> &tokens, Memc<Macro> &macros, Line &line);
  324. void preprocess(Memc<Macro> &macros, Int &line_index, Memc<Token*> &temp, Bool allow_defines, Memc<PrepCond> &prep_if); // check for special preprocessor tokens (#define, #undef, #if, #ifdef, #ifndef, #else, #elif, #endif)
  325. void detectDefines();
  326. void preprocess(Int from=0, Int num=-1);
  327. //
  328. void setTokenPtrs(); // set continuous tokens for the whole file
  329. void changed (Int from, Int num=1);
  330. void exist (Int x, Int y);
  331. Token* findPrevToken(C VecI2 &pos, Int &i);
  332. Token* findToken (C VecI2 &pos, Int &i);
  333. // expression
  334. Bool evaluateSymbol(Int start, Expr &out, Int final=-1, Bool allow_func_lists=false); // returns true if 'out' expression was returned
  335. Symbol* finalSymbol(Int final, Bool allow_func_lists=false);
  336. // suggestions
  337. void clearSuggestions ();
  338. void listSuggestions (Int force=0); // -2=project element, -1=false, 0=autodetect, 1=true
  339. void refreshSuggestions ();
  340. void suggestionsSetRect();
  341. void setSuggestion (Int x);
  342. void autoComplete (Bool auto_space=true, Bool set_undo=true, Bool auto_brace=true, Bool call_changed=true, Bool ignore_params=false);
  343. // detect
  344. Bool getSymbolMacroID (C VecI2 &cur, SymbolPtr &symbol_ptr, Macro* &macro_ptr, UID &id, VecI2 *x_range=null, Bool prefer_definition=false);
  345. void jumpToCur ();
  346. void findAllReferences();
  347. // gui
  348. void visible (Bool visible) {visibleActivate(visible);}
  349. Bool visible ( ) {return super::visible();}
  350. void setOffset ();
  351. void setRegionSize ();
  352. void resize ();
  353. void themeChanged ();
  354. void setGui ();
  355. void prepareForDraw();
  356. void validateView ();
  357. void setView (Bool comments, Bool funcs, Bool func_bodies, Bool private_members);
  358. virtual GuiObj& hide ( ) {clearSuggestions(); return super::hide();}
  359. virtual GuiObj* test (C GuiPC &gpc, C Vec2 &pos, GuiObj* &mouse_wheel);
  360. virtual void update(C GuiPC &gpc);
  361. // draw
  362. void drawSelection(C Color &color, Int y, Int min_x, Int max_x);
  363. void drawSelection(C Color &color, C VecI2 &a, C VecI2 &b, Bool including=false);
  364. virtual void draw (C GuiPC &gpc);
  365. // parse
  366. Symbol* getFullSymbol(Int &i, Str &temp, Symbol *set_parent, Memc<Symbol::Modif> &templates, Symbol* *symbol_parent=null, Int *symbol_index=null) {return GetFullSymbol(tokens, i, temp, set_parent, templates, symbol_parent, symbol_index);}
  367. Symbol* createSpace(Symbol &parent, Int token_index) {return symbols.New().require(parent.full_name+SEP+NamelessName(&parent)).set(&parent, Symbol::SPACE, token_index, parent.source)();}
  368. void delSymbols();
  369. void resetSymbols() {if(!header)delSymbols();}
  370. void detectDataTypes(SymbolPtr parent=null) {if(active)DetectDataTypes(symbols, decls, tokens, parent);}
  371. void linkDataTypes( ) {if(active) LinkDataTypes(symbols, tokens );}
  372. void detectVarFuncs( ) {if(active) DetectVarFuncs(symbols, tokens );}
  373. Bool isDeclaration(Symbol *symbol, Int i) {return IsDeclaration(tokens, symbol, i);}
  374. void parseFunc (Symbol &func, Memc<Command> &cmds, Memc<Message> &msgs); // parse specified 'func' function and setup 'cmds' and 'msgs'
  375. void parseFunc (Symbol &func ); // parse specified 'func' function
  376. void parseFunc (Token &token); // parse function at 'token' token
  377. void parseFunc (C VecI2 &cur ); // parse function at 'cur' cursor position
  378. void parseCurFunc( ); // parse function at cursor position
  379. // C++
  380. void srcTokenRange( Int t_start, Int t_end, VecI2 &start, VecI2 &end);
  381. Bool destTokenRange(Memc<CodeLine> &clines, Int t_start, Int t_end, VecI2 &start, VecI2 &end);
  382. Str getText(Int start, Int end);
  383. void writeAll( Str &out , C VecI2 &start, C VecI2 &end);
  384. void write( Str &out , C VecI2 &start, C VecI2 &end);
  385. void write(Memc<CodeLine> &clines, C VecI2 &start, C VecI2 &end, VecI2 *clines_start=null, Int *line_i=null);
  386. void write(Memc<CodeLine> &clines, Int start, Int end, VecI2 *clines_start=null, Int *line_i=null);
  387. void writeTokens(CodeLine &cline, Int start, Int end, Bool gcc);
  388. void writeSymbolDecl(Memc<CodeLine> &clines, Symbol &symbol, Bool gcc);
  389. void remove (Memc<CodeLine> &clines, Int start, Int end, Bool definite);
  390. void removeDefVal(Memc<CodeLine> &clines, Symbol &symbol);
  391. Int getSymbolStart(Int i);
  392. Int getListEnd (Int i);
  393. Int getBodyStart (Int i);
  394. Int getBodyEnd (Int i);
  395. Bool isFirstVar(Symbol &symbol);
  396. CChar8* adjustDot ( Int i ); // replace '.' with "->" or "::", returns string only if change is needed
  397. void adjustToken(Memc<CodeLine> &code_lines, Int i, Bool gcc); // adjust token from Esenthel Script to C++, 'gcc'=if should be compatible with GCC
  398. void writeClassPath(CodeLine &line, Int col, Symbol *parent, Symbol *cur_namespace, Bool global, Memc<Symbol::Modif> *templates=null, bool start_separator=true);
  399. void expandName ( CodeLine &line, Int col, Symbol &symbol, Symbol *parent, Symbol *cur_namespace);
  400. void expandName (Memc<CodeLine> &code_lines, Symbol &symbol, Symbol *cur_namespace);
  401. void expandRetVal (Memc<CodeLine> &code_lines, Symbol &symbol);
  402. Bool expandableTypename( Symbol &symbol);
  403. Bool expandableTemplate(Int token_index);
  404. void expandTypename (Memc<CodeLine> &code_lines, Symbol &symbol, Int start_line=0);
  405. void expandTemplate (Memc<CodeLine> &code_lines, Int token_index, Int start_line=0);
  406. void expandTemplates (Memc<CodeLine> &code_lines);
  407. void writeClassTemplates(Memc<CodeLine> &clines, Symbol *Class);
  408. void writeCtorInit (Memc<CodeLine> &clines, Symbol &ci , Int &line_i, Bool first, Bool gcc);
  409. void writeCtorInits (Memc<CodeLine> &clines, Symbol &func , Int body_start, Bool gcc);
  410. void writeForcedCtor (Memc<CodeLine> &clines, Symbol &Class, Symbol* &Namespace, Bool gcc);
  411. void detectDefaultCtors();
  412. Bool writeClass (Memc<CodeLine> &clines, Symbol &symbol, Bool gcc);
  413. Bool writeVarFuncs (Memc<CodeLine> &clines, Bool gcc);
  414. Bool writeInline (Memc<CodeLine> &clines, Bool gcc);
  415. Bool writeFunc (Memc<CodeLine> &clines, Bool gcc, Symbol &symbol, Symbol* &Namespace);
  416. Bool writeStaticVars(Memc<CodeLine> &clines, Bool gcc, Symbol* &Namespace, Bool templates);
  417. void makeCPP(C Str &path, C Str &file, Bool gcc, Bool include_headers);
  418. };
  419. #endif
  420. /******************************************************************************/
  421. } // namespace
  422. /******************************************************************************/