PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/FD4/External/Plugins/PHPContext/Context.cs

https://bitbucket.org/kkszysiu/flashdevelop
C# | 389 lines | 248 code | 40 blank | 101 comment | 43 complexity | 03f28d360b348e0d9417f2d32d6ddb1d MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Text.RegularExpressions;
  5. using System.IO;
  6. using PluginCore.Managers;
  7. using ASCompletion.Context;
  8. using ASCompletion.Model;
  9. using PluginCore.Localization;
  10. using PluginCore.Controls;
  11. using PluginCore.Helpers;
  12. using PluginCore;
  13. namespace PHPContext
  14. {
  15. public class Context : AS2Context.Context
  16. {
  17. #region initialization
  18. new static readonly protected Regex re_CMD_BuildCommand =
  19. new Regex("@php[\\s]+(?<params>.*)", RegexOptions.Compiled | RegexOptions.Multiline);
  20. static private readonly Regex re_PHPext =
  21. new Regex(".php[3-9]?", RegexOptions.Compiled);
  22. private ContextSettings langSettings;
  23. private List<InlineRange> phpRanges; // inlined PHP ranges in HTML
  24. public Context(ContextSettings initSettings)
  25. {
  26. langSettings = initSettings;
  27. /* AS-LIKE OPTIONS */
  28. hasLevels = false;
  29. docType = "void";
  30. /* DESCRIBE LANGUAGE FEATURES */
  31. // language constructs
  32. features.hasPackages = false;
  33. features.hasImports = false;
  34. features.hasImportsWildcard = false;
  35. features.hasClasses = true;
  36. features.hasExtends = true;
  37. features.hasImplements = true;
  38. features.hasInterfaces = true;
  39. features.hasEnums = false;
  40. features.hasGenerics = false;
  41. features.hasEcmaTyping = false;
  42. features.hasVars = true;
  43. features.hasConsts = true;
  44. features.hasMethods = true;
  45. features.hasStatics = true;
  46. features.hasTryCatch = true;
  47. features.checkFileName = false;
  48. // allowed declarations access modifiers
  49. Visibility all = Visibility.Public | Visibility.Protected | Visibility.Private;
  50. features.classModifiers = all;
  51. features.varModifiers = all;
  52. features.methodModifiers = all;
  53. // default declarations access modifiers
  54. features.classModifierDefault = Visibility.Public;
  55. features.varModifierDefault = Visibility.Public;
  56. features.methodModifierDefault = Visibility.Public;
  57. // keywords
  58. features.dot = "->";
  59. features.voidKey = "void";
  60. features.objectKey = "Object";
  61. features.typesPreKeys = new string[] { "namespace", "new", "extends", "implements", "as" };
  62. features.codeKeywords = new string[] {
  63. "and", "or", "xor", "exception", "as", "break", "case", "continue", "declare", "default",
  64. "do", "else", "elseif", "enddeclare", "endfor", "endforeach", "endif", "endswitch",
  65. "endwhile", "for", "foreach", "global", "if", "new", "switch", "use", "while",
  66. "try", "catch", "throw"
  67. };
  68. features.varKey = "var";
  69. features.functionKey = "function";
  70. features.staticKey = "static";
  71. features.publicKey = "public";
  72. features.privateKey = "private";
  73. features.intrinsicKey = "extern";
  74. /* INITIALIZATION */
  75. settings = initSettings;
  76. //BuildClassPath(); // defered to first use
  77. }
  78. #endregion
  79. #region classpath management
  80. /// <summary>
  81. /// Classpathes & classes cache initialisation
  82. /// </summary>
  83. public override void BuildClassPath()
  84. {
  85. ReleaseClasspath();
  86. started = true;
  87. if (langSettings == null) throw new Exception("BuildClassPath() must be overridden");
  88. if (contextSetup == null)
  89. {
  90. contextSetup = new ContextSetupInfos();
  91. contextSetup.Lang = settings.LanguageId;
  92. contextSetup.Platform = "PHP";
  93. contextSetup.Version = "5.0";
  94. }
  95. //
  96. // Class pathes
  97. //
  98. classPath = new List<PathModel>();
  99. // intrinsic language definitions
  100. if (langSettings.LanguageDefinitions != null)
  101. {
  102. string langPath = PathHelper.ResolvePath(langSettings.LanguageDefinitions);
  103. if (Directory.Exists(langPath)) AddPath(langPath);
  104. }
  105. // add external pathes
  106. List<PathModel> initCP = classPath;
  107. classPath = new List<PathModel>();
  108. if (contextSetup.Classpath != null)
  109. {
  110. foreach (string cpath in contextSetup.Classpath)
  111. AddPath(cpath.Trim());
  112. }
  113. // add library
  114. AddPath(Path.Combine(PathHelper.LibraryDir, settings.LanguageId + "/classes"));
  115. // add user pathes from settings
  116. if (settings.UserClasspath != null && settings.UserClasspath.Length > 0)
  117. {
  118. foreach (string cpath in settings.UserClasspath) AddPath(cpath.Trim());
  119. }
  120. // add initial pathes
  121. foreach (PathModel mpath in initCP) AddPath(mpath);
  122. // parse top-level elements
  123. InitTopLevelElements();
  124. if (cFile != null) UpdateTopLevelElements();
  125. // add current temporaty path
  126. if (temporaryPath != null)
  127. {
  128. string tempPath = temporaryPath;
  129. temporaryPath = null;
  130. SetTemporaryPath(tempPath);
  131. }
  132. FinalizeClasspath();
  133. }
  134. /// <summary>
  135. /// Build the file DOM
  136. /// </summary>
  137. /// <param name="filename">File path</param>
  138. protected override void GetCurrentFileModel(string fileName)
  139. {
  140. string ext = Path.GetExtension(fileName);
  141. if (!re_PHPext.IsMatch(ext))
  142. {
  143. cFile = FileModel.Ignore;
  144. UpdateContext(cLine);
  145. }
  146. else
  147. {
  148. cFile = new FileModel(fileName);
  149. cFile.Context = this;
  150. cFile.HasFiltering = true;
  151. ASFileParser parser = new ASFileParser();
  152. parser.ParseSrc(cFile, CurSciControl.Text);
  153. cLine = CurSciControl.LineFromPosition(CurSciControl.CurrentPos);
  154. UpdateContext(cLine);
  155. }
  156. }
  157. /// <summary>
  158. /// Called if a FileModel needs filtering
  159. /// - define inline AS3 ranges
  160. /// </summary>
  161. /// <param name="src"></param>
  162. /// <returns></returns>
  163. public override string FilterSource(string fileName, string src)
  164. {
  165. phpRanges = new List<InlineRange>();
  166. return PhpFilter.FilterSource(src, phpRanges);
  167. }
  168. /// <summary>
  169. /// Called if a FileModel needs filtering
  170. /// - modify parsed model
  171. /// </summary>
  172. /// <param name="model"></param>
  173. /// <returns></returns>
  174. public override void FilterSource(FileModel model)
  175. {
  176. PhpFilter.FilterSource(model, phpRanges);
  177. }
  178. #endregion
  179. #region class resolution
  180. /// <summary>
  181. /// Evaluates the visibility of one given type from another.
  182. /// Caller is responsible of calling ResolveExtends() on 'inClass'
  183. /// </summary>
  184. /// <param name="inClass">Completion context</param>
  185. /// <param name="withClass">Completion target</param>
  186. /// <returns>Completion visibility</returns>
  187. public override Visibility TypesAffinity(ClassModel inClass, ClassModel withClass)
  188. {
  189. // same file
  190. if (withClass != null && inClass.InFile == withClass.InFile)
  191. return Visibility.Public | Visibility.Protected | Visibility.Private;
  192. // inheritance affinity
  193. ClassModel tmp = inClass;
  194. while (!tmp.IsVoid())
  195. {
  196. if (tmp == withClass)
  197. return Visibility.Public | Visibility.Protected;
  198. tmp = tmp.Extends;
  199. }
  200. // same package
  201. if (withClass != null && inClass.InFile.Package == withClass.InFile.Package)
  202. return Visibility.Public;
  203. // public only
  204. else
  205. return Visibility.Public;
  206. }
  207. /// <summary>
  208. /// Return the full project classes list
  209. /// </summary>
  210. /// <returns></returns>
  211. public override MemberList GetAllProjectClasses()
  212. {
  213. return base.GetAllProjectClasses();
  214. }
  215. /// <summary>
  216. /// Retrieves a class model from its name
  217. /// </summary>
  218. /// <param name="cname">Class (short or full) name</param>
  219. /// <param name="inClass">Current file</param>
  220. /// <returns>A parsed class or an empty ClassModel if the class is not found</returns>
  221. public override ClassModel ResolveType(string cname, FileModel inFile)
  222. {
  223. return base.ResolveType(cname, inFile);
  224. }
  225. /// <summary>
  226. /// Prepare intrinsic known vars/methods/classes
  227. /// </summary>
  228. protected override void InitTopLevelElements()
  229. {
  230. string filename = "toplevel" + settings.DefaultExtension;
  231. topLevel = new FileModel(filename);
  232. // search top-level declaration
  233. foreach (PathModel aPath in classPath)
  234. if (File.Exists(Path.Combine(aPath.Path, filename)))
  235. {
  236. filename = Path.Combine(aPath.Path, filename);
  237. topLevel = GetCachedFileModel(filename);
  238. break;
  239. }
  240. if (File.Exists(filename))
  241. {
  242. // copy declarations as file-level (ie. flatten class)
  243. /*ClassModel tlClass = topLevel.GetPublicClass();
  244. if (!tlClass.IsVoid() && tlClass.Members.Count > 0)
  245. {
  246. topLevel.Members = tlClass.Members;
  247. tlClass.Members = null;
  248. topLevel.Classes = new List<ClassModel>();
  249. }*/
  250. }
  251. // not found
  252. else
  253. {
  254. //ErrorHandler.ShowInfo("Top-level elements class not found. Please check your Program Settings.");
  255. }
  256. // special variables
  257. topLevel.Members.Add(new MemberModel("$this", "", FlagType.Variable, Visibility.Public));
  258. topLevel.Members.Add(new MemberModel("self", "", FlagType.Variable, Visibility.Public));
  259. topLevel.Members.Add(new MemberModel("parent", "", FlagType.Variable, Visibility.Public));
  260. topLevel.Members.Sort();
  261. foreach (MemberModel member in topLevel.Members)
  262. member.Flags |= FlagType.Intrinsic;
  263. }
  264. public override void CheckModel(bool onFileOpen)
  265. {
  266. if (!File.Exists(cFile.FileName))
  267. {
  268. // refresh model
  269. base.CheckModel(onFileOpen);
  270. }
  271. }
  272. /// <summary>
  273. /// Update intrinsic known vars
  274. /// </summary>
  275. protected override void UpdateTopLevelElements()
  276. {
  277. MemberModel special;
  278. special = topLevel.Members.Search("$this", 0, 0);
  279. if (special != null)
  280. {
  281. if (!cClass.IsVoid()) special.Type = cClass.Name;
  282. else special.Type = (cFile.Version > 1) ? features.voidKey : docType;
  283. }
  284. special = topLevel.Members.Search("self", 0, 0);
  285. if (special != null)
  286. {
  287. if (!cClass.IsVoid()) special.Type = cClass.Name;
  288. else special.Type = (cFile.Version > 1) ? features.voidKey : docType;
  289. }
  290. special = topLevel.Members.Search("parent", 0, 0);
  291. if (special != null)
  292. {
  293. cClass.ResolveExtends();
  294. ClassModel extends = cClass.Extends;
  295. if (!extends.IsVoid()) special.Type = extends.Name;
  296. else special.Type = (cFile.Version > 1) ? features.voidKey : features.objectKey;
  297. }
  298. }
  299. /// <summary>
  300. /// Retrieves a package content
  301. /// </summary>
  302. /// <param name="name">Package path</param>
  303. /// <param name="lazyMode">Force file system exploration</param>
  304. /// <returns>Package folders and types</returns>
  305. public override FileModel ResolvePackage(string name, bool lazyMode)
  306. {
  307. return base.ResolvePackage(name, lazyMode);
  308. }
  309. #endregion
  310. #region command line compiler
  311. //static public string TemporaryOutputFile;
  312. /// <summary>
  313. /// Retrieve the context's default compiler path
  314. /// </summary>
  315. public override string GetCompilerPath()
  316. {
  317. // to be implemented
  318. return null;
  319. }
  320. /// <summary>
  321. /// Check current file's syntax
  322. /// </summary>
  323. public override void CheckSyntax()
  324. {
  325. // to be implemented
  326. }
  327. override public bool CanBuild
  328. {
  329. get { return false; }
  330. }
  331. /// <summary>
  332. /// Run compiler in the current files's base folder with current classpath
  333. /// </summary>
  334. /// <param name="append">Additional comiler switches</param>
  335. public override void RunCMD(string append)
  336. {
  337. // to be implemented
  338. }
  339. /// <summary>
  340. /// Calls RunCMD with additional parameters taken from the file's doc tag
  341. /// </summary>
  342. public override bool BuildCMD(bool failSilently)
  343. {
  344. // to be implemented
  345. return true;
  346. }
  347. #endregion
  348. }
  349. }