PageRenderTime 48ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/VfpMsBuildTarget/VsIntegration/LanguageService/ContainedLanguage/FoxProIntellisenseProvider.cs

#
C# | 376 lines | 273 code | 51 blank | 52 comment | 32 complexity | b5918fcf40592291c7f384a0124d5623 MD5 | raw file
  1. using System;
  2. using System.CodeDom;
  3. using System.CodeDom.Compiler;
  4. using System.Collections.Generic;
  5. using System.Diagnostics.CodeAnalysis;
  6. using System.Globalization;
  7. using System.Runtime.InteropServices;
  8. using Microsoft.VisualStudio.Shell.Interop;
  9. using Microsoft.VisualStudio.TextManager.Interop;
  10. using FoxPro.CodeDom;
  11. using ErrorHandler = Microsoft.VisualStudio.ErrorHandler;
  12. using VSConstants = Microsoft.VisualStudio.VSConstants;
  13. using VFPX.FoxProIntegration.CodeDomCodeModel;
  14. namespace VFPX.FoxProIntegration.FoxProLanguageService {
  15. /// <summary>
  16. /// This class is used to store the information about one specific instance
  17. /// of EnvDTE.FileCodeModel.
  18. /// </summary>
  19. internal class FileCodeModelInfo {
  20. private EnvDTE.FileCodeModel codeModel;
  21. private uint itemId;
  22. internal FileCodeModelInfo(EnvDTE.FileCodeModel codeModel, uint itemId) {
  23. this.codeModel = codeModel;
  24. this.itemId = itemId;
  25. }
  26. internal EnvDTE.FileCodeModel FileCodeModel {
  27. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  28. get { return codeModel; }
  29. }
  30. internal uint ItemId {
  31. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  32. get { return itemId; }
  33. }
  34. }
  35. /// <summary>
  36. /// This class implements an intellisense provider for Web projects.
  37. /// An intellisense provider is a specialization of a language service where it is able to
  38. /// run as a contained language. The main language service and main editor is usually the
  39. /// HTML editor / language service, but a specific contained language is hosted for fragments
  40. /// like the "script" tags.
  41. /// This object must be COM visible because it will be Co-Created by the host language.
  42. /// </summary>
  43. [ComVisible(true)]
  44. [Guid(FoxProConstants.intellisenseProviderGuidString)]
  45. public sealed class FoxProIntellisenseProvider : IVsIntellisenseProject, IDisposable {
  46. private class SourceFileInfo {
  47. private string fileName;
  48. private uint itemId;
  49. private IVsIntellisenseProjectHost hostProject;
  50. private EnvDTE.FileCodeModel fileCode;
  51. private CodeDomProvider codeProvider;
  52. public SourceFileInfo(string name, uint id) {
  53. this.fileName = name;
  54. this.itemId = id;
  55. }
  56. public IVsIntellisenseProjectHost HostProject {
  57. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  58. get { return hostProject; }
  59. set {
  60. if (this.hostProject != value) {
  61. fileCode = null;
  62. }
  63. this.hostProject = value;
  64. }
  65. }
  66. public CodeDomProvider CodeProvider {
  67. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  68. get { return codeProvider; }
  69. set {
  70. if (value != codeProvider) {
  71. fileCode = null;
  72. }
  73. codeProvider = value;
  74. }
  75. }
  76. public EnvDTE.FileCodeModel FileCodeModel {
  77. get {
  78. // Don't build the object more than once.
  79. if (null != fileCode) {
  80. return fileCode;
  81. }
  82. // Verify that the host project is set.
  83. if (null == hostProject) {
  84. throw new System.InvalidOperationException();
  85. }
  86. // Get the hierarchy from the host project.
  87. object propValue;
  88. ErrorHandler.ThrowOnFailure(hostProject.GetHostProperty((uint)HOSTPROPID.HOSTPROPID_HIERARCHY, out propValue));
  89. IVsHierarchy hierarchy = propValue as IVsHierarchy;
  90. if (null == hierarchy) {
  91. return null;
  92. }
  93. // Try to get the extensibility object for the item.
  94. // NOTE: here we assume that the __VSHPROPID.VSHPROPID_ExtObject property returns a VSLangProj.VSProjectItem
  95. // or a EnvDTE.ProjectItem object. No other kind of extensibility is supported.
  96. propValue = null;
  97. ErrorHandler.ThrowOnFailure(hierarchy.GetProperty(itemId, (int)__VSHPROPID.VSHPROPID_ExtObject, out propValue));
  98. EnvDTE.ProjectItem projectItem = null;
  99. VSLangProj.VSProjectItem vsprojItem = propValue as VSLangProj.VSProjectItem;
  100. if (null == vsprojItem) {
  101. projectItem = propValue as EnvDTE.ProjectItem;
  102. } else {
  103. projectItem = vsprojItem.ProjectItem;
  104. }
  105. if (null == projectItem) {
  106. return null;
  107. }
  108. fileCode = new CodeDomFileCodeModel(projectItem.DTE, projectItem, codeProvider, fileName);
  109. return fileCode;
  110. }
  111. }
  112. public uint ItemId {
  113. get { return this.itemId; }
  114. }
  115. public string Name {
  116. [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
  117. get { return fileName; }
  118. }
  119. }
  120. private class FileCodeModelEnumerator : IEnumerable<FileCodeModelInfo> {
  121. private List<SourceFileInfo> filesInfo;
  122. private IVsIntellisenseProjectHost host;
  123. private CodeDomProvider codeProvider;
  124. public FileCodeModelEnumerator(IEnumerable<SourceFileInfo> files, IVsIntellisenseProjectHost hostProject, CodeDomProvider provider) {
  125. filesInfo = new List<SourceFileInfo>(files);
  126. host = hostProject;
  127. codeProvider = provider;
  128. }
  129. public IEnumerator<FileCodeModelInfo> GetEnumerator() {
  130. foreach (SourceFileInfo info in filesInfo) {
  131. info.HostProject = host;
  132. info.CodeProvider = codeProvider;
  133. FileCodeModelInfo codeInfo = new FileCodeModelInfo(info.FileCodeModel, info.ItemId);
  134. yield return codeInfo;
  135. }
  136. }
  137. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
  138. return (System.Collections.IEnumerator)this.GetEnumerator();
  139. }
  140. }
  141. private IVsIntellisenseProjectHost hostProject;
  142. private FoxProContainedLanguageFactory languageFactory;
  143. private List<string> references;
  144. private Dictionary<uint, SourceFileInfo> files;
  145. private FoxProProvider FoxProProvider;
  146. public FoxProIntellisenseProvider() {
  147. System.Diagnostics.Debug.WriteLine("\n\tFoxProIntellisenseProvider created\n");
  148. references = new List<string>();
  149. files = new Dictionary<uint, SourceFileInfo>();
  150. }
  151. public int AddAssemblyReference(string bstrAbsPath) {
  152. string path = bstrAbsPath.ToUpper(CultureInfo.CurrentCulture);
  153. if (!references.Contains(path)) {
  154. references.Add(path);
  155. if (null != FoxProProvider) {
  156. FoxProProvider.AddReference(path);
  157. }
  158. }
  159. return VSConstants.S_OK;
  160. }
  161. public void Dispose() {
  162. Dispose(true);
  163. }
  164. private void Dispose(bool disposing) {
  165. if (disposing) {
  166. Close();
  167. }
  168. GC.SuppressFinalize(this);
  169. }
  170. public int AddFile(string bstrAbsPath, uint itemid) {
  171. if (VSConstants.S_OK != IsCompilableFile(bstrAbsPath)) {
  172. return VSConstants.S_OK;
  173. }
  174. if (!files.ContainsKey(itemid)) {
  175. files.Add(itemid, new SourceFileInfo(bstrAbsPath, itemid));
  176. }
  177. return VSConstants.S_OK;
  178. }
  179. public int AddP2PReference(object pUnk) {
  180. // Not supported.
  181. return VSConstants.E_NOTIMPL;
  182. }
  183. public int Close() {
  184. this.hostProject = null;
  185. if (null != FoxProProvider) {
  186. FoxProProvider.Dispose();
  187. FoxProProvider = null;
  188. }
  189. return VSConstants.S_OK;
  190. }
  191. public int GetCodeDomProviderName(out string pbstrProvider) {
  192. pbstrProvider = FoxProConstants.FoxProCodeDomProviderName;
  193. return VSConstants.S_OK;
  194. }
  195. public int GetCompilerReference(out object ppCompilerReference) {
  196. ppCompilerReference = null;
  197. return VSConstants.E_NOTIMPL;
  198. }
  199. public int GetContainedLanguageFactory(out IVsContainedLanguageFactory ppContainedLanguageFactory) {
  200. if (null == languageFactory) {
  201. languageFactory = new FoxProContainedLanguageFactory(this);
  202. }
  203. ppContainedLanguageFactory = languageFactory;
  204. return VSConstants.S_OK;
  205. }
  206. public int GetExternalErrorReporter(out IVsReportExternalErrors ppErrorReporter) {
  207. // TODO: Handle the error reporter
  208. ppErrorReporter = null;
  209. return VSConstants.E_NOTIMPL;
  210. }
  211. public int GetFileCodeModel(object pProj, object pProjectItem, out object ppCodeModel) {
  212. ppCodeModel = null;
  213. return VSConstants.E_NOTIMPL;
  214. //EnvDTE.ProjectItem projectItem = pProjectItem as EnvDTE.ProjectItem;
  215. //if (null == projectItem) {
  216. // throw new System.ArgumentException();
  217. //}
  218. //EnvDTE.Property prop = projectItem.Properties.Item("FullPath");
  219. //if (null == prop) {
  220. // throw new System.InvalidOperationException();
  221. //}
  222. //string itemPath = prop.Value as string;
  223. //if (string.IsNullOrEmpty(itemPath)) {
  224. // throw new System.InvalidOperationException();
  225. //}
  226. //SourceFileInfo fileInfo = null;
  227. //foreach (SourceFileInfo sourceInfo in files.Values) {
  228. // if (0 == string.Compare(sourceInfo.Name, itemPath, StringComparison.OrdinalIgnoreCase)) {
  229. // fileInfo = sourceInfo;
  230. // break;
  231. // }
  232. //}
  233. //if (null == fileInfo) {
  234. // throw new System.InvalidOperationException();
  235. //}
  236. //fileInfo.HostProject = hostProject;
  237. //fileInfo.CodeProvider = CodeDomProvider;
  238. //ppCodeModel = fileInfo.FileCodeModel;
  239. //return VSConstants.S_OK;
  240. }
  241. public int GetProjectCodeModel(object pProj, out object ppCodeModel) {
  242. ppCodeModel = null;
  243. return VSConstants.E_NOTIMPL;
  244. }
  245. public int Init(IVsIntellisenseProjectHost pHost) {
  246. this.hostProject = pHost;
  247. return VSConstants.S_OK;
  248. }
  249. public int IsCompilableFile(string bstrFileName) {
  250. string ext = System.IO.Path.GetExtension(bstrFileName);
  251. if (0 == string.Compare(ext, FoxProConstants.FoxProFileExtension, StringComparison.OrdinalIgnoreCase)) {
  252. return VSConstants.S_OK;
  253. }
  254. return VSConstants.S_FALSE;
  255. }
  256. public int IsSupportedP2PReference(object pUnk) {
  257. // P2P references are not supported.
  258. return VSConstants.S_FALSE;
  259. }
  260. public int IsWebFileRequiredByProject(out int pbReq) {
  261. pbReq = 0;
  262. return VSConstants.S_OK;
  263. }
  264. public int RefreshCompilerOptions() {
  265. return VSConstants.S_OK;
  266. }
  267. public int RemoveAssemblyReference(string bstrAbsPath) {
  268. string path = bstrAbsPath.ToUpper(CultureInfo.CurrentCulture);
  269. if (references.Contains(path)) {
  270. references.Remove(path);
  271. FoxProProvider = null;
  272. }
  273. return VSConstants.S_OK;
  274. }
  275. public int RemoveFile(string bstrAbsPath, uint itemid) {
  276. if (files.ContainsKey(itemid)) {
  277. files.Remove(itemid);
  278. }
  279. return VSConstants.S_OK;
  280. }
  281. public int RemoveP2PReference(object pUnk) {
  282. return VSConstants.S_OK;
  283. }
  284. public int RenameFile(string bstrAbsPath, string bstrNewAbsPath, uint itemid) {
  285. return VSConstants.S_OK;
  286. }
  287. public int ResumePostedNotifications() {
  288. // No-Op
  289. return VSConstants.S_OK;
  290. }
  291. public int StartIntellisenseEngine() {
  292. // No-Op
  293. return VSConstants.S_OK;
  294. }
  295. public int StopIntellisenseEngine() {
  296. // No-Op
  297. return VSConstants.S_OK;
  298. }
  299. public int SuspendPostedNotifications() {
  300. // No-Op
  301. return VSConstants.S_OK;
  302. }
  303. public int WaitForIntellisenseReady() {
  304. // No-Op
  305. return VSConstants.S_OK;
  306. }
  307. internal FoxProProvider CodeDomProvider {
  308. get {
  309. if (null == FoxProProvider) {
  310. FoxProProvider = new FoxProProvider();
  311. foreach (string assembly in references) {
  312. FoxProProvider.AddReference(assembly);
  313. }
  314. }
  315. return FoxProProvider;
  316. }
  317. }
  318. internal IEnumerable<FileCodeModelInfo> FileCodeModels {
  319. get {
  320. List<SourceFileInfo> allFiles = new List<SourceFileInfo>(files.Values);
  321. return new FileCodeModelEnumerator(allFiles, hostProject, CodeDomProvider);
  322. }
  323. }
  324. }
  325. }