// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; using System.Collections; using System.Collections.Generic; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; namespace ICSharpCode.PythonBinding { public class PythonResolverContext { ICompilationUnit compilationUnit; IProjectContent projectContent; IClass callingClass; string fileContent; ExpressionResult expressionResult; public PythonResolverContext(ParseInformation parseInfo) : this(parseInfo, String.Empty) { } public PythonResolverContext(ParseInformation parseInfo, string fileContent) : this(parseInfo, new ExpressionResult(), fileContent) { } public PythonResolverContext(ParseInformation parseInfo, ExpressionResult expressionResult, string fileContent) { this.fileContent = fileContent; this.expressionResult = expressionResult; GetCompilationUnit(parseInfo); GetProjectContent(); GetCallingMember(); } void GetCompilationUnit(ParseInformation parseInfo) { if (parseInfo != null) { compilationUnit = parseInfo.CompilationUnit; } } void GetProjectContent() { if (compilationUnit != null) { projectContent = compilationUnit.ProjectContent; } } /// /// Determines the class and member at the specified /// line and column in the specified file. /// void GetCallingMember() { if (projectContent != null) { GetCallingClass(); } } /// /// Gets the calling class at the specified line and column. /// void GetCallingClass() { if (compilationUnit.Classes.Count > 0) { callingClass = compilationUnit.Classes[0]; } } public string FileContent { get { return fileContent; } } public IProjectContent ProjectContent { get { return projectContent; } } public ExpressionResult ExpressionResult { get { return expressionResult; } } public MemberName CreateExpressionMemberName() { return new MemberName(Expression); } public string Expression { get { return expressionResult.Expression; } } public ExpressionContext ExpressionContext { get { return expressionResult.Context; } } public DomRegion ExpressionRegion { get { return expressionResult.Region; } } public bool HasProjectContent { get { return projectContent != null; } } public IClass CallingClass { get { return callingClass; } } public bool HasCallingClass { get { return callingClass != null; } } public bool NamespaceExistsInProjectReferences(string name) { return projectContent.NamespaceExists(name); } public bool PartialNamespaceExistsInProjectReferences(string name) { foreach (IProjectContent referencedContent in projectContent.ThreadSafeGetReferencedContents()) { if (PartialNamespaceExists(referencedContent, name)) { return true; } } return false; } bool PartialNamespaceExists(IProjectContent projectContent, string name) { foreach (string namespaceReference in projectContent.NamespaceNames) { if (namespaceReference.StartsWith(name)) { return true; } } return false; } public IClass GetClass(string fullyQualifiedName) { return projectContent.GetClass(fullyQualifiedName, 0); } /// /// Returns an array of the types that are imported by the /// current compilation unit. /// public List GetImportedTypes() { List types = new List(); CtrlSpaceResolveHelper.AddImportedNamespaceContents(types, compilationUnit, callingClass); return types; } public bool HasImport(string name) { foreach (IUsing u in compilationUnit.UsingScope.Usings) { foreach (string ns in u.Usings) { if (name == ns) { return true; } } } return false; } /// /// Looks in the imported namespaces for a class that /// matches the class name. The class name searched for is not fully /// qualified. /// /// The unqualified class name. public IClass GetImportedClass(string name) { foreach (object obj in GetImportedTypes()) { IClass c = obj as IClass; if (c != null) { if (IsSameClassName(name, c.Name)) { return c; } } } return null; } /// /// Determines whether the two type names are the same. /// static bool IsSameClassName(string name1, string name2) { return name1 == name2; } /// /// Looks for the module name where the specified identifier is imported from. /// public string GetModuleForImportedName(string name) { foreach (IUsing u in compilationUnit.UsingScope.Usings) { PythonFromImport pythonFromImport = u as PythonFromImport; if (pythonFromImport != null) { if (pythonFromImport.IsImportedName(name)) { return pythonFromImport.Module; } } } return null; } /// /// Converts a name into the correct identifier name based on any from import as statements. /// public string UnaliasImportedName(string name) { foreach (IUsing u in compilationUnit.UsingScope.Usings) { PythonFromImport pythonFromImport = u as PythonFromImport; if (pythonFromImport != null) { string actualName = pythonFromImport.GetOriginalNameForAlias(name); if (actualName != null) { return actualName; } } } return name; } /// /// Converts the module name to its original unaliased value if it exists. /// public string UnaliasImportedModuleName(string name) { foreach (IUsing u in compilationUnit.UsingScope.Usings) { PythonImport pythonImport = u as PythonImport; if (pythonImport != null) { string actualName = pythonImport.GetOriginalNameForAlias(name); if (actualName != null) { return actualName; } } } return name; } public string[] GetModulesThatImportEverything() { List modules = new List(); foreach (IUsing u in compilationUnit.UsingScope.Usings) { PythonFromImport pythonFromImport = u as PythonFromImport; if (pythonFromImport != null) { if (pythonFromImport.ImportsEverything) { modules.Add(pythonFromImport.Module); } } } return modules.ToArray(); } public bool IsStartOfDottedModuleNameImported(string fullDottedModuleName) { return FindStartOfDottedModuleNameInImports(fullDottedModuleName) != null; } public string FindStartOfDottedModuleNameInImports(string fullDottedModuleName) { MemberName memberName = new MemberName(fullDottedModuleName); while (memberName.HasName) { string partialNamespace = memberName.Type; if (HasImport(partialNamespace)) { return partialNamespace; } memberName = new MemberName(partialNamespace); } return null; } public string UnaliasStartOfDottedImportedModuleName(string fullDottedModuleName) { string startOfModuleName = FindStartOfDottedModuleNameInImports(fullDottedModuleName); if (startOfModuleName != null) { return UnaliasStartOfDottedImportedModuleName(startOfModuleName, fullDottedModuleName); } return fullDottedModuleName; } string UnaliasStartOfDottedImportedModuleName(string startOfModuleName, string fullModuleName) { string unaliasedStartOfModuleName = UnaliasImportedModuleName(startOfModuleName); return unaliasedStartOfModuleName + fullModuleName.Substring(startOfModuleName.Length); } public bool HasDottedImportNameThatStartsWith(string importName) { string dottedImportNameStartsWith = importName + "."; foreach (IUsing u in compilationUnit.UsingScope.Usings) { foreach (string ns in u.Usings) { if (ns.StartsWith(dottedImportNameStartsWith)) { return true; } } } return false; } public PythonResolverContext Clone(string newExpression) { ParseInformation parseInfo = new ParseInformation(compilationUnit); ExpressionResult newExpressionResult = new ExpressionResult(newExpression); return new PythonResolverContext(parseInfo, newExpressionResult, fileContent); } } }