You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
313 lines
8.2 KiB
313 lines
8.2 KiB
// 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; |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Determines the class and member at the specified |
|
/// line and column in the specified file. |
|
/// </summary> |
|
void GetCallingMember() |
|
{ |
|
if (projectContent != null) { |
|
GetCallingClass(); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Gets the calling class at the specified line and column. |
|
/// </summary> |
|
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); |
|
} |
|
|
|
/// <summary> |
|
/// Returns an array of the types that are imported by the |
|
/// current compilation unit. |
|
/// </summary> |
|
public List<ICompletionEntry> GetImportedTypes() |
|
{ |
|
List<ICompletionEntry> types = new List<ICompletionEntry>(); |
|
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; |
|
} |
|
|
|
/// <summary> |
|
/// Looks in the imported namespaces for a class that |
|
/// matches the class name. The class name searched for is not fully |
|
/// qualified. |
|
/// </summary> |
|
/// <param name="name">The unqualified class name.</param> |
|
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; |
|
} |
|
|
|
/// <summary> |
|
/// Determines whether the two type names are the same. |
|
/// </summary> |
|
static bool IsSameClassName(string name1, string name2) |
|
{ |
|
return name1 == name2; |
|
} |
|
|
|
/// <summary> |
|
/// Looks for the module name where the specified identifier is imported from. |
|
/// </summary> |
|
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; |
|
} |
|
|
|
/// <summary> |
|
/// Converts a name into the correct identifier name based on any from import as statements. |
|
/// </summary> |
|
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; |
|
} |
|
|
|
/// <summary> |
|
/// Converts the module name to its original unaliased value if it exists. |
|
/// </summary> |
|
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<string> modules = new List<string>(); |
|
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); |
|
} |
|
} |
|
}
|
|
|