PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/src/poseidon/intellisense/autocomplete.d

http://poseidonide.googlecode.com/
D | 1371 lines | 1072 code | 174 blank | 125 comment | 137 complexity | 08403ae4b1b01d4600854d2ae683cc3c MD5 | raw file
  1. module poseidon.intellisense.autocomplete;
  2. private
  3. {
  4. import Analyzer.D.syntax.CoreAnalyzer;
  5. import poseidon.intellisense.search;
  6. import std.string;
  7. import poseidon.controller.gui;
  8. import poseidon.controller.packageexplorer;
  9. }
  10. const char[][] keywords_d = [ /*"Pascal", "Windows",*/ "abstract", "alias", "align", "asm", "assert", "auto", "body", "bool", "break", "byte",
  11. "case", "cast", "catch", "cdouble", "cent", "cfloat", "char", "class", "const", "continue",
  12. "creal", "dchar", "debug", "default", "delegate", "delete", "deprecated", "do", "double",
  13. "else", "enum", "export", "extern", "false", "final", "finally", "float", "for", "foreach", "function",
  14. "goto", "idouble", "if", "ifloat", "import", "inout", "int", "interface", "invariant",
  15. "ireal", "is", "lazy", "long", "mixin", "module", "new", "null",/*
  16. "opAddAssign", "opAndAssign", "opApply", "opCall", "opCast", "opCatAssign", "opDivAssign",
  17. "opIndex", "opIndexAssign", "opMulAssign", "opModAssign", "opOrAssign", "opPostInc",
  18. "opPostDec", "opSubAssign", "opXorAssign", "opSlice", "opShlAssign", "opShrAssign", "opUShrAssign",*/
  19. "out", "override", "package", "pragma", "private", "protected", "public",
  20. "real", "ref", "return", "scope", "short", "static", "struct", "super", "switch", "synchronized",
  21. "template", "this", "throw", "true", "try", "typedef", "typeid", "typeof",
  22. "ubyte", "ucent", "uint", "ulong", "union", "unittest", "ushort",
  23. "version", "void", "volatile", "wchar", "while", "with" ];
  24. interface IComplete
  25. {
  26. char[][] rootSearch( char[] root );
  27. }
  28. // KeywordComplete
  29. class KeywordComplete:IComplete
  30. {
  31. char[][] rootSearch( char[] root )
  32. {
  33. char[][] results;
  34. if( root.length ) char_rootSearchR( 0, keywords_d.length - 1, std.string.tolower( root ) , keywords_d, results );
  35. return results;
  36. }
  37. }
  38. // ImportComplete
  39. class ImportComplete:IComplete
  40. {
  41. char[][] dirs;
  42. char[][] baseDirs;
  43. void addDirs( char[] base, char[][] d )
  44. {
  45. baseDirs ~= base;
  46. dirs ~= d;
  47. }
  48. char[] _filterResults( char[][] results )
  49. {
  50. char[][] uniques;
  51. foreach( char[] r; results )
  52. {
  53. if( std.path.getExt( r ) == "d" )
  54. uniques ~= r[0 .. $ - 2]; // ???????d,????
  55. else
  56. if( r.find(".") == -1 ) uniques ~= r;
  57. }
  58. if( uniques.length )
  59. return std.string.join( uniques.sort, "?22 " ) ~ "?22";
  60. else
  61. return null;
  62. }
  63. char[] initialImports()
  64. {
  65. char[][] results;
  66. foreach( char[] dir; baseDirs )
  67. results ~= std.file.listdir( dir );
  68. return _filterResults(results);
  69. }
  70. char[] autoCSearch( char[] path )
  71. {
  72. return _filterResults( rootSearch( path ) );
  73. }
  74. char[][] rootSearch( char[] path )
  75. {
  76. char[][] results;
  77. foreach ( char[] dir; dirs )
  78. {
  79. if ( dir.length > path.length )
  80. {
  81. if( dir[( dir.length - path.length )..$] == path )
  82. {
  83. results = std.file.listdir( dir ); // ?dir????????????--????????,???
  84. break;
  85. }
  86. }
  87. }
  88. return results;
  89. }
  90. }
  91. // MRUComplete
  92. class MRUComplete : IComplete
  93. {
  94. private char[][] items;
  95. void addItem( char[] i )
  96. {
  97. i = i.strip();
  98. if ( ! TArray!(char[]).array_contains( items, i ) ) items ~= i; // make sure its unique
  99. }
  100. char[][] rootSearch( char[] root )
  101. {
  102. char[][] results;
  103. if( root.length ) char_rootSearchR( 0, items.length - 1, std.string.tolower( root ) , items, results );
  104. return results;
  105. }
  106. }
  107. // AutoComplete
  108. class AutoComplete
  109. {
  110. private import poseidon.globals;
  111. private import dwt.all;
  112. // ???????,????projaect ? +++SYSTEM_PROJECT+++ -> projectParsers[+++SYSTEM_PROJECT+++]
  113. CAnalyzerTreeNode[char[]][char[]] projectParsers;
  114. CAnalyzerTreeNode[char[]][char[]] defaultParsers;
  115. CAnalyzerTreeNode fileParser;
  116. //private char[] fileParserPath;
  117. KeywordComplete keywordParser;
  118. MRUComplete mruParser;
  119. ImportComplete importParser;
  120. this()
  121. {
  122. keywordParser = new KeywordComplete;
  123. mruParser = new MRUComplete;
  124. importParser = new ImportComplete;
  125. }
  126. void setFileParser( CAnalyzerTreeNode f ){ fileParser = f; }
  127. //void setFileParserPath( char[] path ){ fileParserPath = path; }
  128. //char[] getFileParserPath(){ return fileParserPath;}
  129. CAnalyzerTreeNode getProjectParser( char[] fileName )
  130. {
  131. if( !projectParsers.length ) return null;
  132. char[] projectName = sGUI.packageExp.getActiveProjectName();
  133. if( projectName in projectParsers )
  134. {
  135. if( fileName in projectParsers[projectName] )
  136. return projectParsers[projectName][fileName];
  137. else
  138. return null;
  139. }
  140. else
  141. return null;
  142. }
  143. private void _message( Object args )
  144. {
  145. StringObj s = cast(StringObj) args;
  146. sGUI.outputPanel.appendString( s.data );
  147. }
  148. void addProjectParser( char[][] paths )
  149. {
  150. char[] projectName = sGUI.packageExp.getActiveProjectName();
  151. Display display = Display.getDefault();
  152. foreach( char[] s; paths )
  153. {
  154. if( !std.string.icmp( std.path.getExt( s ), "d" ) || !std.string.icmp( std.path.getExt( s ), "di" ) )
  155. {
  156. try
  157. {
  158. projectParsers[projectName][s] = Analyzer.D.syntax.CoreAnalyzer.parseFileHSU( s );
  159. if( Globals.backLoadParser )
  160. display.asyncExec( new StringObj( "File[ "~ s ~ " ] Parsed.\n" ) , &_message );
  161. else
  162. sGUI.outputPanel.appendString( "File[ "~ s ~ " ] Parsed.\n" );
  163. }
  164. catch( Exception e )
  165. {
  166. if( Globals.backLoadParser )
  167. display.asyncExec( new StringObj( " File[ "~ s ~ " ] Parsed Error.\n" ) , &_message );
  168. else
  169. {
  170. sGUI.outputPanel.setForeColor( 0, 0, 0 );
  171. sGUI.outputPanel.appendString( " File[ "~ s ~ " ] Parsed Error.\n" );
  172. }
  173. }
  174. }
  175. }
  176. if( Globals.parseAllModule ) setAdditionImportModules();
  177. }
  178. void refreshFileParser( char[][] paths )
  179. {
  180. char[] projectName = sGUI.packageExp.getActiveProjectName();
  181. if( projectName in projectParsers )
  182. {
  183. /+
  184. foreach( char[] key; projectParsers[projectName].keys )
  185. {
  186. if( key.length > 5 )
  187. if( key[0..5] == "<ana>" ) continue;
  188. bool bMatch;
  189. foreach( char[] fileName; paths )
  190. {
  191. if( key == fileName )
  192. {
  193. bMatch = true;
  194. break;
  195. }
  196. }
  197. if( !bMatch ) removeSingleFileParser( key, projectName );
  198. }
  199. +/
  200. foreach( char[] fileName; paths )
  201. if( !( fileName in projectParsers[projectName] ) ) addSingleFileParser( fileName, projectName );
  202. }
  203. else
  204. addProjectParser( paths );
  205. }
  206. void updateProjectParser( CAnalyzerTreeNode analyzer, char[] fileName )
  207. {
  208. char[] projectName = sGUI.packageExp.getActiveProjectName();
  209. if( projectName in projectParsers )
  210. {
  211. if( fileName in projectParsers[projectName] )
  212. {
  213. bool BReverseFileParse;
  214. CAnalyzerTreeNode parser = projectParsers[projectName][fileName];
  215. delete parser;
  216. if( analyzer !is null )
  217. {
  218. projectParsers[projectName][fileName] = analyzer;
  219. sGUI.outputPanel.setForeColor( 0, 0, 0 );
  220. sGUI.outputPanel.appendString( "Project[ " ~ projectName ~ " ][ "~ fileName ~ " ] Parser Updated.\n" );
  221. }
  222. else
  223. {
  224. projectParsers[projectName].remove( fileName );
  225. }
  226. }
  227. else
  228. {
  229. if( analyzer !is null )
  230. {
  231. projectParsers[projectName][fileName] = analyzer;
  232. sGUI.outputPanel.setForeColor( 0, 0, 0 );
  233. sGUI.outputPanel.appendString( "Project[ " ~ projectName ~ " ][ "~ fileName ~ " ] Parser Added.\n" );
  234. }
  235. }
  236. }
  237. else
  238. {
  239. if( analyzer )
  240. {
  241. projectParsers[projectName][fileName] = analyzer;
  242. sGUI.outputPanel.setForeColor( 0, 0, 0 );
  243. sGUI.outputPanel.appendString( "Project[ " ~ projectName ~ " ][ "~ fileName ~ " ] Parser Added.\n" );
  244. }
  245. }
  246. }
  247. bool addSingleFileParser( char[] fileName, char[] projectName )
  248. {
  249. if( projectName in projectParsers )
  250. {
  251. if( fileName in projectParsers[projectName] )
  252. {
  253. CAnalyzerTreeNode t = projectParsers[projectName][fileName];
  254. if( t ) delete t;
  255. }
  256. try
  257. {
  258. projectParsers[projectName][fileName] = Analyzer.D.syntax.CoreAnalyzer.parseFileHSU( fileName );
  259. sGUI.outputPanel.setForeColor( 0, 0, 0 );
  260. sGUI.outputPanel.appendString( "Project[ " ~ projectName ~ " ][ "~ fileName ~ " ] Parser Added.\n" );
  261. return true;
  262. }
  263. catch( Exception e )
  264. {
  265. if( fileName in projectParsers[projectName] ) projectParsers[projectName].remove( fileName );
  266. return false;
  267. }
  268. }
  269. return false;
  270. }
  271. bool removeSingleFileParser( char[] fileName, char[] projectName )
  272. {
  273. if( projectName in projectParsers )
  274. {
  275. if( fileName in projectParsers[projectName] )
  276. {
  277. CAnalyzerTreeNode t = projectParsers[projectName][fileName];
  278. if( t ) delete t;
  279. projectParsers[projectName].remove( fileName );
  280. sGUI.outputPanel.setForeColor( 0, 0, 0 );
  281. sGUI.outputPanel.appendString( "Removed File[ " ~ fileName ~ " ] Parser.\n" );
  282. return true;
  283. }
  284. }
  285. return false;
  286. }
  287. bool renSingleFileParser( char[] fileName, char[] newFileName, char[] projectName )
  288. {
  289. if( projectName in projectParsers )
  290. {
  291. if( fileName in projectParsers[projectName] )
  292. {
  293. projectParsers[projectName][newFileName] = projectParsers[projectName][fileName].dup();
  294. projectParsers[projectName].remove( fileName );
  295. sGUI.outputPanel.appendString( "Rename File[ " ~ fileName ~ " ] To [ " ~ newFileName ~ " ].\n" );
  296. return true;
  297. }
  298. }
  299. return false;
  300. }
  301. void deleteProjectParser( char[] projectName )
  302. {
  303. if( projectName in projectParsers )
  304. {
  305. foreach( CAnalyzerTreeNode t; projectParsers[projectName] )
  306. if( t ) delete t;
  307. projectParsers.remove( projectName );
  308. sGUI.outputPanel.setForeColor( 0, 0, 0 );
  309. sGUI.outputPanel.appendString( "Removed project[ " ~ projectName ~ " ].\n" );
  310. }
  311. }
  312. void loadDefaultParser( char[] dir )
  313. {
  314. try
  315. {
  316. CFindAllFile stdFiles = new CFindAllFile( dir );
  317. char[][] files = stdFiles.getFiles();
  318. char[] defaultParserName = std.string.tolower( std.path.getBaseName( dir ) );
  319. sGUI.outputPanel.appendLine( "Default Paser[ " ~ defaultParserName ~ " ] Loading......" );
  320. sGUI.outputPanel.setForeColor( 0, 160, 0 );
  321. foreach( char[] s; files )
  322. {
  323. if( std.path.getExt( s ) == "ana" )
  324. {
  325. CAnalyzerTreeNode tempAnalyzer = Analyzer.D.syntax.nodeHsu.loadAnalyzerNode( s );
  326. if( tempAnalyzer )
  327. {
  328. char[] moduleName = tempAnalyzer.getLeaf( 0 ).identifier;
  329. defaultParsers[defaultParserName][moduleName] = tempAnalyzer;
  330. sGUI.outputPanel.appendLine( "[ " ~ moduleName ~ " ] " ~ "Loaded." );
  331. }
  332. else
  333. {
  334. sGUI.outputPanel.appendLine( " The .ana File[ " ~ s ~ " ] may be broken" );
  335. }
  336. }
  337. }
  338. sGUI.outputPanel.appendLine( "......Load Finish.\n" );
  339. }
  340. catch( Exception e )
  341. {
  342. char[] defaultParserName = std.string.tolower( std.path.getBaseName( dir ) );
  343. sGUI.outputPanel.appendLine(dir);
  344. sGUI.outputPanel.appendLine( " Default Parser [ " ~ defaultParserName ~ " ] Load Error. ( Wrong Parser Path )" );
  345. // MessageBox.showMessage( e.toString );
  346. // throw new Exception( "Load Default Parser Error!" );
  347. }
  348. }
  349. char[] forceComplete( char[] word )
  350. {
  351. /*
  352. char[][] words;
  353. words = mruParser.rootSearch( word );
  354. words ~= keywordParser.rootSearch( word );
  355. // ????? CAnalyzerTreeNode
  356. CAnalyzerTreeNode[] treeNodes = search( word, D_ALL );
  357. foreach( CAnalyzerTreeNode t; treeNodes )
  358. word ~= t.identifier;
  359. // ?????words
  360. TArray!(char[]).sort( words, &icharCompare );
  361. char[][] uniques = TArray!(char[]).array_unique( words );
  362. char[] ret = std.string.join( uniques, " " );
  363. return ret;
  364. */return null;
  365. }
  366. char[][] setMemberImage( CAnalyzerTreeNode[] nodes )
  367. {
  368. if( !nodes.length ) return null;
  369. char[][] words;
  370. foreach( CAnalyzerTreeNode t; nodes )
  371. {
  372. int m, v;
  373. switch( t.DType )
  374. {
  375. case D_FUNCTION: m = 0; break;
  376. case D_VARIABLE: m = 1; break;
  377. case D_CLASS: m = 2; break;
  378. case D_STRUCT: m = 3; break;
  379. case D_INTERFACE: m = 4; break;
  380. case D_UNION: m = 5; break;
  381. case D_ENUM: m = 6; break;
  382. case D_PARAMETER:
  383. words ~= ( t.identifier ~ "?24" );
  384. continue;
  385. break;
  386. /+
  387. case D_ENUMMEMBER:
  388. words ~= ( t.identifier ~ "?25" );
  389. continue;
  390. break;
  391. +/
  392. case D_TEMPLATE:
  393. words ~= ( t.identifier ~ "?26" );
  394. continue;
  395. break;
  396. case D_IMPORT:
  397. if( t.typeIdentifier.length )
  398. words ~= ( t.typeIdentifier ~ "?22" );
  399. else
  400. {
  401. int dotPos = std.string.find( t.identifier, "." );
  402. if( dotPos < 0 ) dotPos = t.identifier.length;
  403. words ~= ( t.identifier[0..dotPos] ~ "?22" );
  404. }
  405. continue;
  406. break;
  407. default:
  408. words ~= ( t.identifier ~ "?23" );
  409. continue;
  410. break;
  411. }
  412. if( t.prot & D_Private )
  413. v = 0;
  414. else if( t.prot & D_Protected )
  415. v = 1;
  416. else
  417. v = 2;
  418. words ~= ( t.identifier ~ "?" ~ std.string.toString( m * 3 + v ) );
  419. }
  420. if( !words.length ) return null;
  421. scope CCharsSort!( char[] ) sortList = new CCharsSort!( char[] )( words );
  422. words = sortList.pop();
  423. char[] prevWord = words[0];
  424. char[][] newWords;
  425. newWords ~= words[0];
  426. for( int i = 1; i < words.length; ++ i )
  427. {
  428. if( words[i] != prevWord )
  429. {
  430. prevWord = words[i];
  431. newWords ~= words[i];
  432. }
  433. }
  434. return newWords;
  435. }
  436. char[] autoCSearch( char[] word, CAnalyzerTreeNode headNode )
  437. {
  438. char[][] words;
  439. char[] ret;
  440. words = mruParser.rootSearch( word );
  441. words ~= keywordParser.rootSearch( word );
  442. if( words.length )
  443. {
  444. TArray!(char[]).sort( words, &icharCompare );
  445. char[][] uniques = TArray!(char[]).array_unique( words );
  446. ret = std.string.join( uniques, "?21 " ) ~ "?21";
  447. }
  448. if( fileParser )
  449. {
  450. char[][] treeWords;
  451. CAnalyzerTreeNode[] treeNodesSum;
  452. if( !headNode )
  453. treeNodesSum = getAnalyzerAllNode( fileParser, D_ALL - D_MODULE - D_BLOCK );
  454. else
  455. {
  456. treeNodesSum = getAnalyzerAllNodeR( headNode, D_ALL - D_MODULE - D_BLOCK );
  457. CAnalyzerTreeNode[] importModules;
  458. //if( getImport( "dummy", D_ALL, headNode, importModules, true ) !is null )
  459. //{
  460. getImport( "dummy", D_ALL, headNode, importModules, true );
  461. int DType = D_UDTS | D_FUNCTION | D_ALIAS | D_TYPEDEF | D_VARIABLE | D_IMPORT;
  462. foreach( CAnalyzerTreeNode a; importModules )
  463. {
  464. foreach( CAnalyzerTreeNode t; a.getAllLeaf() )
  465. {
  466. if( !( t.prot & D_Private ) && !( t.prot & D_Protected ) )
  467. if( t.DType & DType ) treeNodesSum ~= t;
  468. }
  469. }
  470. //}
  471. }
  472. if( treeNodesSum.length )
  473. {
  474. CAnalyzerTreeNode[] treeNodes = rootSearch( word, treeNodesSum );
  475. treeWords = setMemberImage( treeNodes );
  476. if( treeWords.length )
  477. {
  478. if( words.length )
  479. ret = ret ~ " " ~ std.string.join( treeWords, " " );
  480. else
  481. ret = std.string.join( treeWords, " " );
  482. }
  483. }
  484. }
  485. return ret;
  486. }
  487. /+
  488. char[] autoCSearch( char[] word, CAnalyzerTreeNode headNode )
  489. {
  490. char[][] words;
  491. words = mruParser.rootSearch( word );
  492. words ~= keywordParser.rootSearch( word );
  493. if( !words.length ) // if no keywords or MRU
  494. {
  495. if( fileParser )
  496. {
  497. CAnalyzerTreeNode[] treeNodesSum;
  498. if( !headNode )
  499. treeNodesSum = getAnalyzerAllNode( fileParser, D_ALL - D_MODULE - D_BLOCK );
  500. else
  501. {
  502. treeNodesSum = getAnalyzerAllNodeR( headNode, D_ALL - D_MODULE - D_BLOCK );
  503. CAnalyzerTreeNode[] importModules;
  504. getImport( "dummy", D_ALL, headNode, importModules, true );
  505. int DType = D_UDTS | D_FUNCTION | D_ALIAS | D_TYPEDEF | D_VARIABLE | D_IMPORT;
  506. foreach( CAnalyzerTreeNode a; importModules )
  507. {
  508. foreach( CAnalyzerTreeNode t; a.getAllLeaf() )
  509. {
  510. if( !( t.prot & D_Private ) && !( t.prot & D_Protected ) )
  511. if( t.DType & DType ) treeNodesSum ~= t;
  512. }
  513. }
  514. }
  515. if( !treeNodesSum.length ) return null;
  516. CAnalyzerTreeNode[] treeNodes = rootSearch( word, treeNodesSum );
  517. words = setMemberImage( treeNodes );
  518. if( !words.length ) return null;
  519. return std.string.join( words, " " );
  520. }
  521. return null;
  522. }
  523. if( !words.length ) return null;
  524. TArray!(char[]).sort( words, &icharCompare );
  525. char[][] uniques = TArray!(char[]).array_unique( words );
  526. char[] ret = std.string.join( uniques, "?21 " ) ~ "?21";
  527. return ret;
  528. }
  529. +/
  530. // ??????? CAnalyzerTreeNode ( CAnalyzerTreeNode.name = ... )
  531. CAnalyzerTreeNode[] search( char[] word, int typeFlag = D_ALL, bool bPassFilePaser = false )
  532. {
  533. CAnalyzerTreeNode[] treeNodes;
  534. if( !fileParser ) return null;
  535. if( word.length )
  536. {
  537. if( !bPassFilePaser )
  538. if( !treeNodes.length ) treeNodes ~= lookAnalyzerTree( word, typeFlag, fileParser );
  539. if( !treeNodes.length ) // ?????Parser
  540. {
  541. char[] projectName = sGUI.packageExp.getActiveProjectName();
  542. foreach ( CAnalyzerTreeNode p; projectParsers[projectName] )
  543. if( p != fileParser ) treeNodes ~= lookAnalyzerTree( word, typeFlag, p );
  544. }
  545. }
  546. return treeNodes;
  547. }
  548. // ????->??????????????? CAnalyzerTreeNode
  549. CAnalyzerTreeNode[] lookAnalyzerTree( char[] ident, int typeFlag = D_ALL, CAnalyzerTreeNode activeTreeNode = null )
  550. {
  551. if( !ident.length ) return null;
  552. if( !activeTreeNode ) return null;
  553. CAnalyzerTreeNode[] analyzerTreeNodes;
  554. // Nested Function
  555. void _lookingFormHead( CAnalyzerTreeNode treeNode )
  556. {
  557. if( treeNode.DType & typeFlag )
  558. if( treeNode.identifier == ident ) analyzerTreeNodes ~= treeNode;
  559. foreach( CAnalyzerTreeNode t; treeNode.getAllLeaf() )
  560. _lookingFormHead( t );
  561. }
  562. _lookingFormHead( activeTreeNode );
  563. return analyzerTreeNodes;
  564. }
  565. // ????????????? CAnalyzerTreeNode
  566. CAnalyzerTreeNode getAnalyzerTreeNode( char[] ident, int typeFlag = D_ALL, CAnalyzerTreeNode activeTreeNode = null,
  567. bool bBottomLook = false )
  568. {
  569. if( !ident.length ) return null;
  570. if( !activeTreeNode ) return null;
  571. CAnalyzerTreeNode analyzerTreeNode;
  572. if( bBottomLook ) // ?????????
  573. {
  574. foreach( CAnalyzerTreeNode t; activeTreeNode.getAllLeaf() )
  575. {
  576. if( t.DType & typeFlag )
  577. if( t.identifier == ident ) return t;
  578. }
  579. }
  580. // Nested Function
  581. void _lookingFormNode( CAnalyzerTreeNode treeNode )
  582. {
  583. if( analyzerTreeNode ) return;
  584. CAnalyzerTreeNode rootNode = treeNode.getRoot();
  585. if( rootNode )
  586. {
  587. _lookingFormNode( rootNode );
  588. foreach( CAnalyzerTreeNode t; rootNode.getAllLeaf() )
  589. {
  590. if( t.DType & typeFlag )
  591. {
  592. if( t.identifier == ident )
  593. {
  594. analyzerTreeNode = t;
  595. break;
  596. }
  597. }
  598. }
  599. }
  600. }
  601. _lookingFormNode( activeTreeNode );
  602. return analyzerTreeNode;
  603. }
  604. // ????????
  605. CAnalyzerTreeNode[] getBaseClassNode( CAnalyzerTreeNode treeNode )
  606. {
  607. CAnalyzerTreeNode[] baseClassNodes;
  608. void _getNode( CAnalyzerTreeNode node )
  609. {
  610. if( !node.baseClass.length ) return;
  611. char[][] className = std.string.split( treeNode.baseClass, "," );
  612. CAnalyzerTreeNode[] nestClasses;
  613. foreach( char[] s; className )
  614. {
  615. int DType = D_CLASS | D_INTERFACE;
  616. char[][] templateClassName = std.string.split( s, "!" );
  617. s = templateClassName[0];
  618. if( templateClassName.length > 1 ) DType = DType | D_TEMPLATE;
  619. // ???class??Parser
  620. CAnalyzerTreeNode activeTreeNode = getAnalyzerTreeNode( s, DType, node, true );
  621. if( !activeTreeNode )
  622. {
  623. CAnalyzerTreeNode[] dummyAnalyzers;
  624. activeTreeNode = getImport( s, DType, node, dummyAnalyzers );
  625. if( activeTreeNode )
  626. {
  627. if( DType & D_TEMPLATE )
  628. {
  629. foreach( CAnalyzerTreeNode t; activeTreeNode.getAllLeaf() )
  630. {
  631. if( t.DType == D_CLASS || t.DType == D_INTERFACE )
  632. if( t.identifier == s )
  633. activeTreeNode = t;
  634. }
  635. }
  636. baseClassNodes ~= activeTreeNode;
  637. nestClasses ~= activeTreeNode;
  638. }
  639. }else
  640. {
  641. if( DType & D_TEMPLATE )
  642. {
  643. foreach( CAnalyzerTreeNode t; activeTreeNode.getAllLeaf() )
  644. {
  645. if( t.DType == D_CLASS || t.DType == D_INTERFACE )
  646. if( t.identifier == s )
  647. activeTreeNode = t;
  648. }
  649. }
  650. baseClassNodes ~= activeTreeNode;
  651. }
  652. }
  653. foreach( CAnalyzerTreeNode t; nestClasses )
  654. {
  655. if( t.DType & D_INTERFACE ) _getNode( t );
  656. }
  657. }
  658. _getNode( treeNode );
  659. return baseClassNodes;
  660. }
  661. // ??
  662. CAnalyzerTreeNode getMemberAnalyzerTreeNode( char[] ident, int typeFlag = D_ALL, CAnalyzerTreeNode activeTreeNode = null, inout CAnalyzerTreeNode[] baseClasses = null )
  663. {
  664. if( !ident.length ) return null;
  665. if( !activeTreeNode ) return null;
  666. foreach( CAnalyzerTreeNode t; activeTreeNode.getAllLeaf() )
  667. {
  668. version( Windows )
  669. {
  670. if( t.DType & D_VERSION )
  671. {
  672. if( t.identifier == "Windows" || t.identifier == "Win32" )
  673. {
  674. CAnalyzerTreeNode versionNodeResult = getMemberAnalyzerTreeNode( ident, typeFlag, t, baseClasses );
  675. if( versionNodeResult ) return versionNodeResult;
  676. }
  677. continue;
  678. }
  679. }
  680. if( t.DType & typeFlag )
  681. if( t.identifier == ident ) return t;
  682. }
  683. // ?????????????
  684. if( activeTreeNode.baseClass.length )
  685. {
  686. baseClasses = getBaseClassNode( activeTreeNode );
  687. foreach( CAnalyzerTreeNode t; baseClasses )
  688. {
  689. foreach( CAnalyzerTreeNode tt; t.getAllLeaf() )
  690. {
  691. if( tt.DType & typeFlag )
  692. if( tt.identifier == ident )
  693. return tt;
  694. }
  695. }
  696. }
  697. return null;
  698. }
  699. CAnalyzerTreeNode[] getAnalyzerAllNode( CAnalyzerTreeNode node, int DType = D_ALL )
  700. {
  701. CAnalyzerTreeNode[] result;
  702. if( node.DType & D_MAINROOT )
  703. {
  704. void _getLeaf( CAnalyzerTreeNode _node )
  705. {
  706. if( _node.DType & DType )
  707. {
  708. result ~= _node;
  709. foreach( CAnalyzerTreeNode t; _node.getAllLeaf() ) _getLeaf( t );
  710. }
  711. }
  712. _getLeaf( node );
  713. return result;
  714. }
  715. return null;
  716. }
  717. CAnalyzerTreeNode[] getAnalyzerAllNodeR( CAnalyzerTreeNode node, int DType = D_ALL )
  718. {
  719. if( !node ) return null;
  720. CAnalyzerTreeNode[] results;
  721. // Nested Function
  722. void _lookingFormNode( CAnalyzerTreeNode treeNode )
  723. {
  724. if( treeNode )
  725. {
  726. foreach( CAnalyzerTreeNode t; treeNode.getAllLeaf() )
  727. if( t.DType & DType ) results ~= t;
  728. _lookingFormNode( treeNode.getRoot() );
  729. }
  730. }
  731. _lookingFormNode( node );
  732. return results;
  733. }
  734. // ??????????????
  735. void setAdditionImportModules( CAnalyzerTreeNode singleModule = null )
  736. {
  737. int[char[]] importedModuleNameArray;
  738. bool bFirstImport = true;
  739. char[] projectName = sGUI.packageExp.getActiveProjectName();
  740. Display display = Display.getDefault();
  741. if( singleModule is null )
  742. {
  743. if( Globals.backLoadParser )
  744. display.asyncExec( new StringObj( "\nAddition Parser Load......\n" ) , &_message );
  745. else
  746. sGUI.outputPanel.appendString( "\nAddition Parser Load......\n" );
  747. }
  748. else
  749. {
  750. if( Globals.backLoadParser )
  751. display.asyncExec( new StringObj( "" ) , &_message );
  752. else
  753. sGUI.outputPanel.appendLine( "" );
  754. }
  755. void _addParser( CAnalyzerTreeNode[] parsers )
  756. {
  757. if( !parsers.length ) return;
  758. CAnalyzerTreeNode[] addAnalyzers;
  759. char[][] addImportNames;
  760. foreach( CAnalyzerTreeNode parser; parsers )
  761. {
  762. CAnalyzerTreeNode[] analyzerTreeNodes;
  763. foreach( CAnalyzerTreeNode t; getAnalyzerAllNode( parser ) )
  764. if( t.DType & D_IMPORT )
  765. {
  766. if( bFirstImport )
  767. analyzerTreeNodes ~= t;
  768. else
  769. {
  770. if( t.prot & D_Public ) analyzerTreeNodes ~= t;
  771. }
  772. }
  773. foreach( CAnalyzerTreeNode t; analyzerTreeNodes )
  774. {
  775. if( !( t.identifier in importedModuleNameArray ) )
  776. {
  777. addImportNames ~= t.identifier;
  778. importedModuleNameArray[t.identifier] = 1;
  779. }
  780. }
  781. }
  782. int countAddImportModule = addImportNames.length;
  783. if( countAddImportModule == 0 ) return;
  784. int count;
  785. foreach( char[] moduleName; addImportNames )
  786. {
  787. bool bGetDefaultparser;
  788. char[][] splitModuleName = std.string.split( moduleName, "." );
  789. char[] anaModuleName, defaultParserName, defaultParserFileName;
  790. if( splitModuleName.length > 1 )
  791. {
  792. defaultParserName = Globals.poseidonPath ~ "\\ana\\" ~ splitModuleName[0];
  793. if( std.file.exists( defaultParserName ) )
  794. {
  795. for( int i = 1; i < splitModuleName.length; ++ i )
  796. anaModuleName ~= ( "-" ~ splitModuleName[i] );
  797. anaModuleName = anaModuleName[1..length];
  798. defaultParserFileName = defaultParserName ~ "\\" ~ anaModuleName ~ ".ana";
  799. if( std.file.exists( defaultParserFileName ) )
  800. {
  801. try
  802. {
  803. CAnalyzerTreeNode defaultParserNode = loadAnalyzerNode( defaultParserFileName );
  804. char[] mName, fName;
  805. getModuleNames( defaultParserNode, mName, fName );
  806. projectParsers[projectName][fName] = defaultParserNode;
  807. addAnalyzers ~= defaultParserNode;
  808. if( Globals.backLoadParser )
  809. display.asyncExec( new StringObj( "Module[ "~ moduleName ~ " ] Loaded And Parsed.\n" ) , &_message );
  810. else
  811. sGUI.outputPanel.appendString( "Module[ "~ moduleName ~ " ] Loaded And Parsed.\n" );
  812. bGetDefaultparser = true;
  813. count ++;
  814. if( count >= countAddImportModule ) break;
  815. }
  816. catch( Exception e )
  817. {
  818. if( Globals.backLoadParser )
  819. display.asyncExec( new StringObj( " Module[ "~ moduleName ~ " ] Parsed Error.\n" ) , &_message );
  820. else
  821. sGUI.outputPanel.appendString( " Module[ "~ moduleName ~ " ] Parsed Error.\n" );
  822. }
  823. }
  824. }
  825. }
  826. if( !bGetDefaultparser )
  827. {
  828. foreach( char[] path; sGUI.packageExp.activeProject().projectIncludePaths ~ Globals.scINIImportPath )
  829. {
  830. char[] name = std.string.replace( moduleName, ".", "\\" );
  831. name = std.path.join( path, name );// ~".d";
  832. try
  833. {
  834. CAnalyzerTreeNode extraParser = Analyzer.D.syntax.CoreAnalyzer.parseFileHSU( name ~ ".di" );
  835. projectParsers[projectName][name ~ ".di"] = extraParser;
  836. addAnalyzers ~= extraParser;
  837. if( Globals.backLoadParser )
  838. display.asyncExec( new StringObj( "File[ "~ name ~ ".di ] Loaded And Parsed.\n" ) , &_message );
  839. else
  840. sGUI.outputPanel.appendString( "File[ "~ name ~ ".di ] Loaded And Parsed.\n" );
  841. count ++;
  842. if( count >= countAddImportModule ) break;
  843. }
  844. catch( Exception e )
  845. {
  846. try
  847. {
  848. CAnalyzerTreeNode extraParser = Analyzer.D.syntax.CoreAnalyzer.parseFileHSU( name ~ ".d" );
  849. projectParsers[projectName][name ~ ".d"] = extraParser;
  850. addAnalyzers ~= extraParser;
  851. if( Globals.backLoadParser )
  852. display.asyncExec( new StringObj( "File[ "~ name ~ ".d ] Loaded And Parsed.\n" ) , &_message );
  853. else
  854. sGUI.outputPanel.appendString( "File[ "~ name ~ ".d ] Loaded And Parsed.\n" );
  855. count ++;
  856. if( count >= countAddImportModule ) break;
  857. }
  858. catch( Exception e )
  859. {
  860. if( e.toString != "NoExist" )
  861. {
  862. if( Globals.backLoadParser )
  863. display.asyncExec( new StringObj( " File[ "~ name ~ " ] Parsed Error.\n" ) , &_message );
  864. else
  865. sGUI.outputPanel.appendString( " File[ "~ name ~ " ] Parsed Error.\n" );
  866. }
  867. }
  868. }
  869. }
  870. if( count >= countAddImportModule ) break;
  871. }
  872. }
  873. bFirstImport = false;
  874. _addParser( addAnalyzers );
  875. }
  876. CAnalyzerTreeNode[] parserGroup;
  877. foreach( CAnalyzerTreeNode t; projectParsers[projectName] )
  878. {
  879. if( t !is null )
  880. {
  881. char[] mName, mFullPath;
  882. getModuleNames( t, mName, mFullPath );
  883. importedModuleNameArray[mName] = 1;
  884. if( singleModule is null ) parserGroup ~= t;
  885. }
  886. }
  887. if( singleModule !is null ) parserGroup ~= singleModule;
  888. _addParser( parserGroup );
  889. if( singleModule is null )
  890. {
  891. if( Globals.backLoadParser )
  892. display.asyncExec( new StringObj( "All Done.\n" ) , &_message );
  893. else
  894. sGUI.outputPanel.appendString( "All Done.\n" );
  895. }
  896. }
  897. public void getModuleNames( CAnalyzerTreeNode node, inout char[] _moduleName, inout char[] _moduleFullPath )
  898. {
  899. while( !( node.DType & D_MAINROOT ) )
  900. node = node.getRoot();
  901. foreach( CAnalyzerTreeNode t; node.getAllLeaf() )
  902. {
  903. if( t.DType & D_MODULE )
  904. {
  905. _moduleName = t.identifier;
  906. _moduleFullPath = t.typeIdentifier;
  907. return;
  908. }
  909. }
  910. }
  911. CAnalyzerTreeNode getImport( char[] word, int typeFlag, CAnalyzerTreeNode activeTreeNode, out CAnalyzerTreeNode[] importedModules, bool bGetModules = false )
  912. {
  913. bool bInRootModule = true;
  914. int[char[]] importedModuleNameArray;
  915. CAnalyzerTreeNode[] importModules;
  916. //char[][] modulesName;
  917. CAnalyzerTreeNode ret;
  918. CAnalyzerTreeNode activeParser;
  919. char[] projectName = sGUI.packageExp.getActiveProjectName();
  920. char[] mName, mFullPath;
  921. if( activeTreeNode ) getModuleNames( activeTreeNode, mName, mFullPath );
  922. if( !activeTreeNode )
  923. activeParser = fileParser;
  924. else
  925. activeParser = getProjectParser( mFullPath );
  926. if( !activeParser || !word.length ) return null;
  927. importedModuleNameArray[mName] = 1;
  928. // Nested Function
  929. bool _inProjectParser( char[] m )
  930. {
  931. foreach( CAnalyzerTreeNode[char[]] t; defaultParsers )
  932. if( m in t ) return true;
  933. foreach( CAnalyzerTreeNode t; projectParsers[projectName] )
  934. {
  935. if( t !is null )
  936. {
  937. char[] name, fullPath;
  938. getModuleNames( t, name, fullPath );
  939. if( name == m ) return true;
  940. }
  941. }
  942. return false;
  943. }
  944. CAnalyzerTreeNode _getProjectParserByModuleName( char[] m )
  945. {
  946. foreach( CAnalyzerTreeNode[char[]] t; defaultParsers )
  947. if( m in t ) return t[m];
  948. //if( m in defaultParsers["std"] ) return defaultParsers["std"][m];
  949. foreach( CAnalyzerTreeNode t; projectParsers[projectName] )
  950. {
  951. if( t !is null )
  952. {
  953. char[] name, fullPath;
  954. getModuleNames( t, name, fullPath );
  955. if( name == m ) return projectParsers[projectName][fullPath];
  956. }
  957. }
  958. return null;
  959. }
  960. // Nested Function
  961. void _lookingFormHead( CAnalyzerTreeNode treeNode )
  962. {
  963. if( ret ) return;
  964. while( !( treeNode.DType & D_MAINROOT ) ) treeNode = treeNode.getRoot();
  965. foreach( CAnalyzerTreeNode t; treeNode.getAllLeaf() )
  966. {
  967. if( !( t.prot & ( D_Private | D_Protected ) ) )
  968. {
  969. if( t.DType & typeFlag )
  970. {
  971. if( t.identifier == word )
  972. {
  973. ret = t;
  974. return;
  975. }
  976. }
  977. }
  978. }
  979. }
  980. // ?????????? D_IMPORT CAnalyzerTreeNode
  981. CAnalyzerTreeNode[] _getFirstImportNodes()
  982. {
  983. CAnalyzerTreeNode[] analyzerTreeNodes;
  984. if( !activeTreeNode ) return null;
  985. foreach( CAnalyzerTreeNode t; activeTreeNode.getAllLeaf() )
  986. if( t.DType & D_IMPORT ) analyzerTreeNodes ~= t;
  987. // Nested Function
  988. void _lookingFormNode( CAnalyzerTreeNode treeNode )
  989. {
  990. CAnalyzerTreeNode rootNode = treeNode.getRoot();
  991. if( rootNode )
  992. {
  993. foreach( CAnalyzerTreeNode t; rootNode.getAllLeaf() )
  994. {
  995. if( t.DType & D_IMPORT ) analyzerTreeNodes ~= t;
  996. }
  997. _lookingFormNode( rootNode );
  998. }
  999. }
  1000. _lookingFormNode( activeTreeNode );
  1001. return analyzerTreeNodes;
  1002. }
  1003. void _findImport( CAnalyzerTreeNode analyzer )
  1004. {
  1005. char[][] insidemodulesName;
  1006. if( analyzer )
  1007. {
  1008. if( bInRootModule ) // ?????import
  1009. {
  1010. CAnalyzerTreeNode[] importFirst = _getFirstImportNodes();
  1011. foreach( CAnalyzerTreeNode t; importFirst )
  1012. {
  1013. if( !( t.identifier in importedModuleNameArray ) )
  1014. {
  1015. if( _inProjectParser( t.identifier ) )
  1016. {
  1017. insidemodulesName ~= t.identifier;
  1018. importedModuleNameArray[t.identifier] = 1;
  1019. }
  1020. }
  1021. }
  1022. }
  1023. else
  1024. {
  1025. foreach( CAnalyzerTreeNode t; analyzer.getAllLeaf() )
  1026. {
  1027. if( t.DType & D_IMPORT )
  1028. {
  1029. if( !( t.identifier in importedModuleNameArray ) )
  1030. {
  1031. if( t.prot & D_Public )
  1032. {
  1033. if( _inProjectParser( t.identifier ) )
  1034. {
  1035. insidemodulesName ~= t.identifier;
  1036. importedModuleNameArray[t.identifier] = 1;
  1037. }
  1038. }
  1039. }
  1040. }
  1041. }
  1042. }
  1043. }else
  1044. return;
  1045. bInRootModule = false;
  1046. if( insidemodulesName.length )
  1047. {
  1048. //modulesName.length = 0;
  1049. //modulesName ~= insidemodulesName;
  1050. foreach( char[] s; insidemodulesName )
  1051. {
  1052. CAnalyzerTreeNode a = _getProjectParserByModuleName( s );
  1053. if( a )
  1054. {
  1055. importModules ~= a;
  1056. _findImport( a );
  1057. }
  1058. }
  1059. }
  1060. }
  1061. _findImport( activeParser );
  1062. if( bGetModules )
  1063. {
  1064. //sGUI.outputPanel.appendString( "modules.length = " ~ std.string.toString( importModules.length ) ~ "\n" );
  1065. /+
  1066. foreach( CAnalyzerTreeNode a; importModules )
  1067. {
  1068. foreach( CAnalyzerTreeNode t; a.getAllLeaf() )
  1069. {
  1070. if( t.DType & D_MODULE )
  1071. {
  1072. sGUI.outputPanel.appendString( "modules.name = " ~ t.identifier ~ "\n" );
  1073. break;
  1074. }
  1075. }
  1076. //sGUI.outputPanel.appendString( "modules.name = " ~ a.identifier ~ "\n" );
  1077. }
  1078. +/
  1079. importedModules = importModules;
  1080. return null;
  1081. }
  1082. foreach( CAnalyzerTreeNode a; importModules )
  1083. {
  1084. //sGUI.outputPanel.appendString( "modules.name = " ~ a.identifier ~ "\n" );
  1085. _lookingFormHead( a );
  1086. if( ret ) break;
  1087. }
  1088. return ret;
  1089. }
  1090. private CAnalyzerTreeNode[] rootSearch( char[] root, CAnalyzerTreeNode[] allListings, int typeFlag = D_ALL )
  1091. {
  1092. CAnalyzerTreeNode[] matches;
  1093. root = std.string.tolower( root );
  1094. //typeFlag = typeFlag - D_IMPORT;
  1095. foreach( CAnalyzerTreeNode t; allListings )
  1096. {
  1097. if( t.DType & D_IMPORT )
  1098. {
  1099. if( t.typeIdentifier.length )
  1100. {
  1101. if( t.typeIdentifier.length >= root.length )
  1102. if( root == std.string.tolower( t.typeIdentifier[0..root.length] ) ) matches ~= t;
  1103. continue;
  1104. }
  1105. }
  1106. if( t.DType & typeFlag )
  1107. if( t.identifier.length )
  1108. if( t.identifier.length >= root.length )
  1109. if( root == std.string.tolower( t.identifier[0..root.length] ) ) matches ~= t;
  1110. }
  1111. return matches;
  1112. }
  1113. }