public void DoNotShowInaccessibleInnerClass() { string program = @"using System; class C { } class Outer { private class Inner { } } "; TypeResolveResult trr = Resolve <TypeResolveResult>(program, "Outer", 3); ArrayList l = trr.GetCompletionData(trr.ResolvedClass.ProjectContent); Assert.IsFalse(IsInnerClassVisible(l)); }
public void GenericInnerClassOrNonGenericOuterClass() { string program = @"using System; class Test { class TheClass<T> {} } class TheClass { } "; TypeResolveResult trr = Resolve <TypeResolveResult>(program, "TheClass<string>", 3); Assert.AreEqual("Test.TheClass", trr.ResolvedClass.FullyQualifiedName); }
public void ShowProtectedInnerClassFromDerivedClass() { string program = @"using System; class Derived : Outer { } class Outer { protected class Inner {} } "; TypeResolveResult trr = Resolve <TypeResolveResult>(program, "Outer", 3); ArrayList l = trr.GetCompletionData(trr.ResolvedClass.ProjectContent); Assert.IsTrue(IsInnerClassVisible(l)); }
public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data) { IReturnType type; if (string.IsNullOrEmpty(memberReferenceExpression.MemberName)) { // NRefactory creates this "dummy" fieldReferenceExpression when it should // parse a primitive type name (int, short; Integer, Decimal) if (memberReferenceExpression.TargetObject is TypeReferenceExpression) { type = TypeVisitor.CreateReturnType(((TypeReferenceExpression)memberReferenceExpression.TargetObject).TypeReference, resolver); return(CreateTypeResolveResult(type)); } } ResolveResult targetRR = Resolve(memberReferenceExpression.TargetObject); if (targetRR == null) { return(null); } type = targetRR.ResolvedType; if (targetRR is NamespaceResolveResult) { return(ResolveMemberInNamespace(((NamespaceResolveResult)targetRR).Name, memberReferenceExpression)); } else if (type != null) { TypeResolveResult typeRR = targetRR as TypeResolveResult; if (typeRR != null && typeRR.ResolvedClass != null) { foreach (IClass c1 in typeRR.ResolvedClass.ClassInheritanceTree) { foreach (IClass c in c1.InnerClasses) { if (resolver.IsSameName(memberReferenceExpression.MemberName, c.Name) && c.TypeParameters.Count == memberReferenceExpression.TypeArguments.Count) { return(CreateTypeResolveResult(resolver.ConstructType(c.DefaultReturnType, memberReferenceExpression.TypeArguments))); } } } } return(resolver.ResolveMember(type, memberReferenceExpression.MemberName, memberReferenceExpression.TypeArguments, NRefactoryResolver.IsInvoked(memberReferenceExpression), typeRR == null, // allow extension methods only for non-static method calls targetRR is BaseResolveResult ? (bool?)true : null // allow calling protected members using "base." )); } return(null); }
public void DoNotShowProtectedInnerClassThroughUnrelatedClass() { string program = @"using System; class Unrelated { } class Derived : Outer { } class Outer { protected class Inner {} } "; TypeResolveResult trr = Resolve <TypeResolveResult>(program, "Derived", 3); ArrayList l = trr.GetCompletionData(trr.ResolvedClass.ProjectContent); Assert.IsFalse(IsInnerClassVisible(l)); }
public override ResolveResult Resolve(CSharpResolver resolver) { ResolveResult rr; if (targetType != null) { rr = new TypeResolveResult(targetType.Resolve(resolver.CurrentTypeResolveContext)); } else { rr = targetExpression.Resolve(resolver); } return(resolver.ResolveMemberAccess(rr, memberName, typeArguments.Resolve(resolver.CurrentTypeResolveContext))); }
public override ResolveResult Resolve(CSharpResolver resolver) { ResolveResult rr; if (targetType != null) { rr = new TypeResolveResult(targetType.Resolve(resolver.Context)); } else { rr = targetExpression.Resolve(resolver); } return(resolver.ResolveMemberAccess(rr, memberName, ConstantIdentifierReference.ResolveTypes(resolver, typeArguments))); }
private void FindReferencesButtonClick(object sender, EventArgs e) { if (csharpTreeView.SelectedNode == null) { return; } IProjectContent project = new CSharpProjectContent(); var unresolvedFile = _syntaxTree.ToTypeSystem(); project = project.AddOrUpdateFiles(unresolvedFile); project = project.AddAssemblyReferences(_builtInLibs.Value); ICompilation compilation = project.CreateCompilation(); CSharpAstResolver resolver = new CSharpAstResolver(compilation, _syntaxTree, unresolvedFile); AstNode node = (AstNode)csharpTreeView.SelectedNode.Tag; IEntity entity; MemberResolveResult mrr = resolver.Resolve(node) as MemberResolveResult; TypeResolveResult trr = resolver.Resolve(node) as TypeResolveResult; if (mrr != null) { entity = mrr.Member; } else if (trr != null) { entity = trr.Type.GetDefinition(); } else { return; } FindReferences fr = new FindReferences(); int referenceCount = 0; FoundReferenceCallback callback = delegate(AstNode matchNode, ResolveResult result) { Debug.WriteLine(matchNode.StartLocation + " - " + matchNode + " - " + result); referenceCount++; }; var searchScopes = fr.GetSearchScopes(entity); Debug.WriteLine("Find references to " + entity.ReflectionName); fr.FindReferencesInFile(searchScopes, unresolvedFile, _syntaxTree, compilation, callback, CancellationToken.None); MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName); }
public void ImportAliasClassResolveTest() { string program = @"using COL = System.Collections.ArrayList; class TestClass { void Test() { COL a = new COL(); } } "; TypeResolveResult rr = Resolve <TypeResolveResult>(program, "COL", 4); Assert.AreEqual("System.Collections.ArrayList", rr.ResolvedClass.FullyQualifiedName, "COL"); LocalResolveResult lr = Resolve <LocalResolveResult>(program, "a", 5); Assert.AreEqual("System.Collections.ArrayList", lr.ResolvedType.FullyQualifiedName, "a"); }
void ResolveArrayCreation(ExpressionCollection arguments) { if (arguments.Count == 2) { ClearResult(); arguments[0].Accept(this); TypeResolveResult trr = resolveResult as TypeResolveResult; if (trr != null) { MakeResult(new ArrayReturnType(projectContent, trr.ResolvedType, 1)); } } else { ResolveMethodInType(new GetClassReturnType(projectContent, "Boo.Lang.Builtins", 0), "array", arguments); } }
public void ImportAliasClassResolveTest() { string program = @"using COL = System.Collections.Generic.List<string>; class TestClass { void Test() { COL a = new COL(); } } "; TypeResolveResult rr = Resolve(program, "COL", 4) as TypeResolveResult; Assert.AreEqual("System.Collections.Generic.List", rr.ResolvedClass.FullyQualifiedName, "COL"); Assert.AreEqual("System.Collections.Generic.List{System.String}", rr.ResolvedType.DotNetName, "COL"); LocalResolveResult lr = Resolve(program, "a", 5) as LocalResolveResult; Assert.AreEqual("System.Collections.Generic.List{System.String}", lr.ResolvedType.DotNetName, "a"); }
void CheckName(TypeDeclaration node, AffectedEntity entity, Identifier identifier, Modifiers accessibilty) { TypeResolveResult resolveResult = ctx.Resolve(node) as TypeResolveResult; if (resolveResult == null) { return; } var type = resolveResult.Type; if (type.DirectBaseTypes.Any(t => t.FullName == "System.Attribute")) { if (CheckNamedResolveResult(resolveResult, node, AffectedEntity.CustomAttributes, identifier, accessibilty)) { return; } } else if (type.DirectBaseTypes.Any(t => t.FullName == "System.EventArgs")) { if (CheckNamedResolveResult(resolveResult, node, AffectedEntity.CustomEventArgs, identifier, accessibilty)) { return; } } else if (type.DirectBaseTypes.Any(t => t.FullName == "System.Exception")) { if (CheckNamedResolveResult(resolveResult, node, AffectedEntity.CustomExceptions, identifier, accessibilty)) { return; } } var typeDef = type.GetDefinition(); if (typeDef != null && typeDef.Attributes.Any(attr => attr.AttributeType.FullName == "NUnit.Framework.TestFixtureAttribute")) { if (CheckNamedResolveResult(resolveResult, node, AffectedEntity.TestType, identifier, accessibilty)) { return; } } CheckNamedResolveResult(resolveResult, node, entity, identifier, accessibilty); }
public void ImportedSubnamespaceTestVBNet() { // using an import this way IS possible in VB.NET string program = @"Imports System Class TestClass Sub Test() Dim a As Collections.ArrayList End Sub End Class "; TypeResolveResult type = ResolveVB <TypeResolveResult>(program, "Collections.ArrayList", 4); Assert.AreEqual("System.Collections.ArrayList", type.ResolvedClass.FullyQualifiedName, "TypeResolveResult"); LocalResolveResult local = ResolveVB <LocalResolveResult>(program, "a", 5); Assert.AreEqual("System.Collections.ArrayList", local.ResolvedType.FullyQualifiedName, "the full type should be resolved"); }
public void ImportAliasTest() { string program = @"using COL = System.Collections; class TestClass { void Test() { COL.ArrayList a; } } "; TypeResolveResult type = Resolve <TypeResolveResult>(program, "COL.ArrayList", 4); Assert.IsNotNull(type, "COL.ArrayList should resolve to a type"); Assert.AreEqual("System.Collections.ArrayList", type.ResolvedClass.FullyQualifiedName, "TypeResolveResult"); LocalResolveResult local = Resolve <LocalResolveResult>(program, "a", 5); Assert.AreEqual("System.Collections.ArrayList", local.ResolvedType.FullyQualifiedName, "the full type should be resolved"); }
public void ResolveNamespaceSD2_863() { string program = @"using System; namespace A.C { class D {} } namespace A.B.C { class D {} } namespace A.B { class TestClass { void Test() { } } } "; NamespaceResolveResult nrr = Resolve <NamespaceResolveResult>(program, "C", 7); Assert.AreEqual("A.B.C", nrr.Name, "nrr.Name"); TypeResolveResult trr = Resolve <TypeResolveResult>(program, "C.D", 7); Assert.AreEqual("A.B.C.D", trr.ResolvedClass.FullyQualifiedName, "trr.ResolvedClass.FullyQualifiedName"); }
public override object VisitMemberReferenceExpression(MemberReferenceExpression fieldReferenceExpression, object data) { ResolveResult fieldRR = base.VisitMemberReferenceExpression(fieldReferenceExpression, data) as ResolveResult; if (vbMyFormsClass != null && IsReferenceToInstanceMember(fieldRR)) { TypeResolveResult trr = Resolve(fieldReferenceExpression.TargetObject) as TypeResolveResult; if (trr != null && trr.ResolvedClass != null) { foreach (IProperty p in vbMyFormsClass.Properties) { if (p.ReturnType.FullyQualifiedName == trr.ResolvedClass.FullyQualifiedName) { fieldReferenceExpression.TargetObject = MakeFieldReferenceExpression("My.MyProject.Forms." + p.Name); } } } } return(null); }
public override object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data) { base.VisitAssignmentExpression(assignmentExpression, data); if (vbMyFormsClass != null) { TypeResolveResult trr = Resolve(assignmentExpression.Right) as TypeResolveResult; if (trr != null && trr.ResolvedClass != null) { foreach (IProperty p in vbMyFormsClass.Properties) { if (p.ReturnType.FullyQualifiedName == trr.ResolvedClass.FullyQualifiedName) { assignmentExpression.Right = MakeFieldReferenceExpression("My.MyProject.Forms." + p.Name); break; } } } } return(null); }
protected static ISymbol GetSymbol(ResolveResult symbol) { TypeResolveResult trr = symbol as TypeResolveResult; if (trr != null) { return(trr.Type.GetDefinition()); } MemberResolveResult mrr = symbol as MemberResolveResult; if (mrr != null) { return(mrr.Member.MemberDefinition); } LocalResolveResult lrr = symbol as LocalResolveResult; if (lrr != null) { return(lrr.Variable); } return(null); }
void UpdateTick(ParserUpdateStepEventArgs e) { this.dynamicHelpTerms.Clear(); ResolveResult res = ResolveAtCaret(e); if (res == null) { return; } if (res != null && res.ResolvedType != null) { this.AddToStringCollection(res.ResolvedType.FullyQualifiedName); } MemberResolveResult member = res as MemberResolveResult; NamespaceResolveResult nspace = res as NamespaceResolveResult; MethodGroupResolveResult method = res as MethodGroupResolveResult; TypeResolveResult types = res as TypeResolveResult; if (member != null && member.ResolvedMember != null) { this.AddToStringCollection(0, member.ResolvedMember.FullyQualifiedName); } if (nspace != null) { this.AddToStringCollection(0, nspace.Name); } if (method != null && method.ContainingType != null) { this.AddToStringCollection(0, method.ContainingType.FullyQualifiedName); } if (types != null && types.ResolvedClass != null) { this.AddToStringCollection(0, types.ResolvedClass.FullyQualifiedName); } BuildDynamicHelpList(); }
public void ShowHelp() { // Resolve expression at cursor and show help TextArea textArea = this.TextArea; IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(this.Adapter.FileName); if (expressionFinder == null) { return; } string textContent = this.Text; ExpressionResult expressionResult = expressionFinder.FindFullExpression(textContent, textArea.Caret.Offset); string expression = expressionResult.Expression; if (!string.IsNullOrEmpty(expression)) { ResolveResult result = ParserService.Resolve(expressionResult, textArea.Caret.Line, textArea.Caret.Column, this.Adapter.FileName, textContent); TypeResolveResult trr = result as TypeResolveResult; if (trr != null) { HelpProvider.ShowHelp(trr.ResolvedClass); } MemberResolveResult mrr = result as MemberResolveResult; if (mrr != null) { switch (mrr.ResolvedMember.DeclaringType.ClassType) { case ClassType.Enum: HelpProvider.ShowHelp(mrr.ResolvedMember.DeclaringType); break; default: HelpProvider.ShowHelp(mrr.ResolvedMember); break; } } } }
// Token: 0x06000011 RID: 17 RVA: 0x000023DC File Offset: 0x000005DC public bool TryResolveType(string identifier, Client.SourceLocation location, out string resolvedType) { resolvedType = null; ProjectDocument document = this.GetDocument(location.FileName); if (document != null) { ResolveResult languageItem = this.GetLanguageItem(document, identifier, location); NamespaceResolveResult namespaceResolveResult = languageItem as NamespaceResolveResult; if (namespaceResolveResult != null) { resolvedType = namespaceResolveResult.NamespaceName; return(true); } TypeResolveResult typeResolveResult = languageItem as TypeResolveResult; if (typeResolveResult != null && !typeResolveResult.IsError) { resolvedType = typeResolveResult.Type.FullName; return(true); } } return(false); }
void AddPropertiesForType(ArrayList result, XmlTextReader r, TypeResolveResult rr) { if (rr.ResolvedType != null) { foreach (IProperty p in rr.ResolvedType.GetProperties()) { if (!p.IsPublic) { continue; } if (!p.CanSet && !IsCollectionType(p.ReturnType)) { continue; } string propPrefix = p.DeclaringType.Name; if (!string.IsNullOrEmpty(r.Prefix)) { propPrefix = r.Prefix + ":" + propPrefix; } result.Add(new XamlCompletionProperty(p, propPrefix)); } } }
public void HandleToolTipRequest(ToolTipRequestEventArgs e) { if (e.ResolveResult == null) { return; } TypeResolveResult trr = e.ResolveResult as TypeResolveResult; MemberResolveResult mrr = e.ResolveResult as MemberResolveResult; LocalResolveResult lrr = e.ResolveResult as LocalResolveResult; if (trr != null && trr.Type.GetDefinition() != null) { e.SetToolTip(CreateTooltip(trr.Type)); } else if (mrr != null) { e.SetToolTip(CreateTooltip(mrr.Member)); } else if (lrr != null) { e.SetToolTip(new FlowDocumentTooltip(XmlDocFormatter.CreateTooltip(lrr.Variable))); } }
static List <Reference> FindReferences(ResolveResult entity, string fileName, IProgressMonitor progressMonitor) { if (entity == null) { throw new ArgumentNullException("entity"); } if (entity is LocalResolveResult) { return(RunFindReferences(entity.CallingClass, (entity as LocalResolveResult).Field, entity.CallingClass.CompilationUnit.FileName, progressMonitor)); } else if (entity is TypeResolveResult) { TypeResolveResult trr = (TypeResolveResult)entity; if (trr.ResolvedClass != null) { return(FindReferences(trr.ResolvedClass, fileName, progressMonitor)); } } else if (entity is MemberResolveResult) { return(FindReferences((entity as MemberResolveResult).ResolvedMember, fileName, progressMonitor)); } else if (entity is MethodGroupResolveResult) { IMethod method = (entity as MethodGroupResolveResult).GetMethodIfSingleOverload(); if (method != null) { return(FindReferences(method, fileName, progressMonitor)); } } else if (entity is MixedResolveResult) { return(FindReferences((entity as MixedResolveResult).PrimaryResult, fileName, progressMonitor)); } return(null); }
public void Resolved(AstNode node, ResolveResult result) { if (ParenthesizedExpression.ActsAsParenthesizedExpression(node)) { return; } MemberResolveResult mrr = result as MemberResolveResult; if (mrr != null) { referenceFound(node, mrr.Member.MemberDefinition); } TypeResolveResult trr = result as TypeResolveResult; if (trr != null) { ITypeDefinition typeDef = trr.Type.GetDefinition(); if (typeDef != null) { referenceFound(node, typeDef); } } }
public override IEntity ResolveCref(string cref) { if (cref.Length > 2 && cref[1] == ':') { // resolve ID string return(base.ResolveCref(cref)); } var documentationReference = new CSharpParser().ParseDocumentationReference(cref); var csharpContext = context as CSharpTypeResolveContext; CSharpResolver resolver; if (csharpContext != null) { resolver = new CSharpResolver(csharpContext); } else { resolver = new CSharpResolver(context.Compilation); } var astResolver = new CSharpAstResolver(resolver, documentationReference); var rr = astResolver.Resolve(documentationReference); MemberResolveResult mrr = rr as MemberResolveResult; if (mrr != null) { return(mrr.Member); } TypeResolveResult trr = rr as TypeResolveResult; if (trr != null) { return(trr.Type.GetDefinition()); } return(null); }
ResolveResult CreateResult(ResolveResult targetResolveResult, List <LookupGroup> lookupGroups, string name, IReadOnlyList <IType> typeArguments) { // Remove all hidden groups lookupGroups.RemoveAll(g => g.AllHidden); if (lookupGroups.Count == 0) { // No members found return(new UnknownMemberResolveResult(targetResolveResult.Type, name, typeArguments)); } if (lookupGroups.Any(g => !g.MethodsAreHidden && g.Methods.Count > 0)) { // If there are methods, make a MethodGroupResolveResult. // Note that a conflict between a member and a method (possible with multiple interface inheritance) // is only a warning, not an error, and the C# compiler will prefer the method group. List <MethodListWithDeclaringType> methodLists = new List <MethodListWithDeclaringType>(); foreach (var lookupGroup in lookupGroups) { if (!lookupGroup.MethodsAreHidden && lookupGroup.Methods.Count > 0) { var methodListWithDeclType = new MethodListWithDeclaringType(lookupGroup.DeclaringType); foreach (var method in lookupGroup.Methods) { methodListWithDeclType.Add((IMethod)method); } methodLists.Add(methodListWithDeclType); } } return(new MethodGroupResolveResult(targetResolveResult, name, methodLists, typeArguments)); } // If there are ambiguities, report the most-derived result (last group) LookupGroup resultGroup = lookupGroups[lookupGroups.Count - 1]; if (resultGroup.NestedTypes != null && resultGroup.NestedTypes.Count > 0) { if (resultGroup.NestedTypes.Count > 1 || !resultGroup.NonMethodIsHidden || lookupGroups.Count > 1) { return(new AmbiguousTypeResolveResult(resultGroup.NestedTypes[0])); } else { return(new TypeResolveResult(resultGroup.NestedTypes[0])); } } if (resultGroup.NonMethod.IsStatic && targetResolveResult is ThisResolveResult) { targetResolveResult = new TypeResolveResult(targetResolveResult.Type); } if (lookupGroups.Count > 1) { return(new AmbiguousMemberResolveResult(targetResolveResult, resultGroup.NonMethod)); } else { if (isInEnumMemberInitializer) { IField field = resultGroup.NonMethod as IField; if (field != null && field.DeclaringTypeDefinition != null && field.DeclaringTypeDefinition.Kind == TypeKind.Enum) { return(new MemberResolveResult( targetResolveResult, field, field.DeclaringTypeDefinition.EnumUnderlyingType, field.IsConst, field.GetConstantValue())); } } return(new MemberResolveResult(targetResolveResult, resultGroup.NonMethod)); } }
public override IType ResolveType(CSharpResolver resolver) { TypeResolveResult trr = Resolve(resolver) as TypeResolveResult; return(trr != null ? trr.Type : new UnknownType(null, identifier, typeArguments.Count)); }
AstType ConvertTypeHelper(ITypeDefinition typeDef, IList <IType> typeArguments) { Debug.Assert(typeArguments.Count >= typeDef.TypeParameterCount); string keyword = KnownTypeReference.GetCSharpNameByTypeCode(typeDef.KnownTypeCode); if (keyword != null) { return(new PrimitiveType(keyword)); } // The number of type parameters belonging to outer classes int outerTypeParameterCount; if (typeDef.DeclaringType != null) { outerTypeParameterCount = typeDef.DeclaringType.TypeParameterCount; } else { outerTypeParameterCount = 0; } if (resolver != null) { // Look if there's an alias to the target type if (UseAliases) { for (ResolvedUsingScope usingScope = resolver.CurrentUsingScope; usingScope != null; usingScope = usingScope.Parent) { foreach (var pair in usingScope.UsingAliases) { if (pair.Value is TypeResolveResult) { if (TypeMatches(pair.Value.Type, typeDef, typeArguments)) { return(new SimpleType(pair.Key)); } } } } } IList <IType> localTypeArguments; if (typeDef.TypeParameterCount > outerTypeParameterCount) { localTypeArguments = new IType[typeDef.TypeParameterCount - outerTypeParameterCount]; for (int i = 0; i < localTypeArguments.Count; i++) { localTypeArguments[i] = typeArguments[outerTypeParameterCount + i]; } } else { localTypeArguments = EmptyList <IType> .Instance; } ResolveResult rr = resolver.ResolveSimpleName(typeDef.Name, localTypeArguments); TypeResolveResult trr = rr as TypeResolveResult; if (trr != null || (localTypeArguments.Count == 0 && resolver.IsVariableReferenceWithSameType(rr, typeDef.Name, out trr))) { if (!trr.IsError && TypeMatches(trr.Type, typeDef, typeArguments)) { // We can use the short type name SimpleType shortResult = new SimpleType(typeDef.Name); AddTypeArguments(shortResult, typeDef, typeArguments, outerTypeParameterCount, typeDef.TypeParameterCount); return(shortResult); } } } if (AlwaysUseShortTypeNames) { var shortResult = new SimpleType(typeDef.Name); AddTypeArguments(shortResult, typeDef, typeArguments, outerTypeParameterCount, typeDef.TypeParameterCount); return(shortResult); } MemberType result = new MemberType(); if (typeDef.DeclaringTypeDefinition != null) { // Handle nested types result.Target = ConvertTypeHelper(typeDef.DeclaringTypeDefinition, typeArguments); } else { // Handle top-level types if (string.IsNullOrEmpty(typeDef.Namespace)) { result.Target = new SimpleType("global"); result.IsDoubleColon = true; } else { result.Target = ConvertNamespace(typeDef.Namespace); } } result.MemberName = typeDef.Name; AddTypeArguments(result, typeDef, typeArguments, outerTypeParameterCount, typeDef.TypeParameterCount); return(result); }
public override ResolveResult Resolve(CSharpResolver resolver) { ResolveResult rr; if (targetType != null) rr = new TypeResolveResult(targetType.Resolve(resolver.Context)); else rr = targetExpression.Resolve(resolver); return resolver.ResolveMemberAccess(rr, memberName, ConstantIdentifierReference.ResolveTypes(resolver, typeArguments)); }
Value Visit(TypeResolveResult result) { throw new GetValueException("Error: Types not supported."); }
string Visit(TypeResolveResult result) { return new CSharpAmbience().ConvertType(result.Type); }
public override ResolveResult Resolve(CSharpResolver resolver) { ResolveResult rr; if (targetType != null) rr = new TypeResolveResult(targetType.Resolve(resolver.CurrentTypeResolveContext)); else rr = targetExpression.Resolve(resolver); return resolver.ResolveMemberAccess(rr, memberName, typeArguments.Resolve(resolver.CurrentTypeResolveContext)); }
protected void VisitMemberReferenceExpression() { MemberReferenceExpression memberReferenceExpression = this.MemberReferenceExpression; int pos = this.Emitter.Output.Length; bool isRefArg = this.Emitter.IsRefArg; this.Emitter.IsRefArg = false; ResolveResult resolveResult = null; ResolveResult expressionResolveResult = null; string targetVar = null; string valueVar = null; bool isStatement = false; bool isConstTarget = false; var targetrr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Target, this.Emitter); if (targetrr is ConstantResolveResult) { isConstTarget = true; } var memberTargetrr = targetrr as MemberResolveResult; if (memberTargetrr != null && memberTargetrr.Type.Kind == TypeKind.Enum && memberTargetrr.Member is DefaultResolvedField && Helpers.EnumEmitMode(memberTargetrr.Type) == 2) { isConstTarget = true; } if (memberReferenceExpression.Target is ParenthesizedExpression || (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.Int64)) || (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.UInt64)) || (targetrr is ConstantResolveResult && targetrr.Type.IsKnownType(KnownTypeCode.Decimal))) { isConstTarget = false; } var isInvoke = memberReferenceExpression.Parent is InvocationExpression && (((InvocationExpression)(memberReferenceExpression.Parent)).Target == memberReferenceExpression); if (isInvoke) { resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter); expressionResolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter); if (expressionResolveResult is InvocationResolveResult) { resolveResult = expressionResolveResult; } else if (expressionResolveResult is MemberResolveResult) { if (((MemberResolveResult)expressionResolveResult).Member is IProperty) { resolveResult = expressionResolveResult; } } } else { resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression, this.Emitter); } bool oldIsAssignment = this.Emitter.IsAssignment; bool oldUnary = this.Emitter.IsUnaryAccessor; if (resolveResult == null) { this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } memberReferenceExpression.Target.AcceptVisitor(this.Emitter); if (isConstTarget) { this.Write(")"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; this.WriteDot(); string name = memberReferenceExpression.MemberName; this.Write(name.ToLowerCamelCase()); return; } bool isDynamic = false; if (resolveResult is DynamicInvocationResolveResult) { var dynamicResolveResult = (DynamicInvocationResolveResult)resolveResult; var group = dynamicResolveResult.Target as MethodGroupResolveResult; if (group != null && group.Methods.Count() > 1) { var method = group.Methods.FirstOrDefault(m => { if (dynamicResolveResult.Arguments.Count != m.Parameters.Count) { return(false); } for (int i = 0; i < m.Parameters.Count; i++) { var argType = dynamicResolveResult.Arguments[i].Type; if (argType.Kind == TypeKind.Dynamic) { argType = this.Emitter.Resolver.Compilation.FindType(TypeCode.Object); } if (!m.Parameters[i].Type.Equals(argType)) { return(false); } } return(true); }) ?? group.Methods.Last(); isDynamic = true; resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method); resolveResult = new InvocationResolveResult(resolveResult, method, dynamicResolveResult.Arguments); } } if (resolveResult is MethodGroupResolveResult) { var oldResult = (MethodGroupResolveResult)resolveResult; resolveResult = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter); if (resolveResult is DynamicInvocationResolveResult) { var method = oldResult.Methods.Last(); resolveResult = new MemberResolveResult(new TypeResolveResult(method.DeclaringType), method); } } MemberResolveResult member = resolveResult as MemberResolveResult; var globalTarget = member != null?this.Emitter.IsGlobalTarget(member.Member) : null; if (member != null && member.Member.Attributes.Any(a => a.AttributeType.FullName == "Bridge.NonScriptableAttribute")) { throw new EmitterException(this.MemberReferenceExpression, "Member " + member.ToString() + " is marked as not usable from script"); } if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod) { var interceptor = this.Emitter.Plugins.OnReference(this, this.MemberReferenceExpression, member); if (interceptor.Cancel) { return; } if (!string.IsNullOrEmpty(interceptor.Replacement)) { this.Write(interceptor.Replacement); return; } } if (globalTarget != null && globalTarget.Item1) { var target = globalTarget.Item2; if (!string.IsNullOrWhiteSpace(target)) { bool assign = false; var memberExpression = member.Member is IMethod ? memberReferenceExpression.Parent.Parent : memberReferenceExpression.Parent; var targetExpression = member.Member is IMethod ? memberReferenceExpression.Parent : memberReferenceExpression; var assignment = memberExpression as AssignmentExpression; if (assignment != null && assignment.Right == targetExpression) { assign = true; } else { var varInit = memberExpression as VariableInitializer; if (varInit != null && varInit.Initializer == targetExpression) { assign = true; } else if (memberExpression is InvocationExpression) { var targetInvocation = (InvocationExpression)memberExpression; if (targetInvocation.Arguments.Any(a => a == targetExpression)) { assign = true; } } } if (assign) { if (resolveResult is InvocationResolveResult) { this.PushWriter(target); } else { this.Write(target); } return; } } if (resolveResult is InvocationResolveResult) { this.PushWriter(""); } return; } Tuple <bool, bool, string> inlineInfo = member != null ? (isDynamic ? ((Emitter)this.Emitter).GetInlineCodeFromMember(member.Member, null) : this.Emitter.GetInlineCode(memberReferenceExpression)) : null; //string inline = member != null ? this.Emitter.GetInline(member.Member) : null; string inline = inlineInfo != null ? inlineInfo.Item3 : null; if (string.IsNullOrEmpty(inline) && member != null && member.Member is IMethod && !(member is InvocationResolveResult) && !( memberReferenceExpression.Parent is InvocationExpression && memberReferenceExpression.NextSibling != null && memberReferenceExpression.NextSibling.Role is TokenRole && ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "(" ) ) { var method = (IMethod)member.Member; if (method.TypeArguments.Count > 0) { inline = MemberReferenceBlock.GenerateInlineForMethodReference(method, this.Emitter); } } if (member != null && member.Member is IMethod && isInvoke) { var i_rr = this.Emitter.Resolver.ResolveNode(memberReferenceExpression.Parent, this.Emitter) as CSharpInvocationResolveResult; if (i_rr != null && !i_rr.IsExpandedForm) { var tpl = this.Emitter.GetAttribute(member.Member.Attributes, JS.NS.BRIDGE + ".TemplateAttribute"); if (tpl != null && tpl.PositionalArguments.Count == 2) { inline = tpl.PositionalArguments[1].ConstantValue.ToString(); } } } bool hasInline = !string.IsNullOrEmpty(inline); bool hasThis = hasInline && Helpers.HasThis(inline); inline = hasInline ? Helpers.ConvertTokens(this.Emitter, inline, member.Member) : inline; bool isInterfaceMember = false; if (hasInline && inline.StartsWith("<self>")) { hasThis = true; inline = inline.Substring(6); } bool nativeImplementation = true; bool isInterface = inline == null && member != null && member.Member.DeclaringTypeDefinition != null && member.Member.DeclaringTypeDefinition.Kind == TypeKind.Interface; var hasTypeParemeter = isInterface && Helpers.IsTypeParameterType(member.Member.DeclaringType); if (isInterface) { var itypeDef = member.Member.DeclaringTypeDefinition; var variance = MetadataUtils.IsJsGeneric(itypeDef, this.Emitter) && itypeDef.TypeParameters != null && itypeDef.TypeParameters.Any(typeParameter => typeParameter.Variance != VarianceModifier.Invariant); if (variance) { isInterfaceMember = true; } else { var ei = this.Emitter.Validator.IsExternalInterface(itypeDef); if (ei != null) { nativeImplementation = ei.IsNativeImplementation; } else { nativeImplementation = member.Member.DeclaringTypeDefinition.ParentAssembly.AssemblyName == CS.NS.ROOT || !this.Emitter.Validator.IsExternalType(member.Member.DeclaringTypeDefinition); } if (ei != null && ei.IsSimpleImplementation) { nativeImplementation = false; isInterfaceMember = false; } else if (ei != null || hasTypeParemeter) { if (hasTypeParemeter || !nativeImplementation) { isInterfaceMember = true; } } } } string interfaceTempVar = null; if (hasThis) { this.Write(""); var oldBuilder = this.Emitter.Output; var oldInline = inline; string thisArg = null; bool isSimple = true; if (this.MemberReferenceExpression.Target is BaseReferenceExpression) { thisArg = "this"; } else { this.Emitter.Output = new StringBuilder(); this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } this.WriteSimpleTarget(resolveResult); if (isConstTarget) { this.Write(")"); } thisArg = this.Emitter.Output.ToString(); if (Regex.Matches(inline, @"\{(\*?)this\}").Count > 1) { var mrr = resolveResult as MemberResolveResult; bool isField = mrr != null && mrr.Member is IField && (mrr.TargetResult is ThisResolveResult || mrr.TargetResult is LocalResolveResult || mrr.TargetResult is MemberResolveResult && ((MemberResolveResult)mrr.TargetResult).Member is IField); isSimple = (mrr != null && (mrr.TargetResult is ThisResolveResult || mrr.TargetResult is ConstantResolveResult || mrr.TargetResult is LocalResolveResult)) || isField; } } int thisIndex; inline = member != null?Helpers.ConvertTokens(this.Emitter, inline, member.Member) : inline; if (!isSimple) { StringBuilder sb = new StringBuilder(); sb.Append("("); var tempVar = this.GetTempVarName(); inline = inline.Replace("{this}", tempVar); thisIndex = tempVar.Length + 2; sb.Append(tempVar); sb.Append(" = "); sb.Append(thisArg); sb.Append(", "); sb.Append(inline); sb.Append(")"); inline = sb.ToString(); } else { thisIndex = inline.IndexOf("{this}", StringComparison.Ordinal); inline = inline.Replace("{this}", thisArg); } if (member != null && member.Member is IProperty) { this.Emitter.Output = new StringBuilder(); inline = inline.Replace("{0}", "[[0]]"); new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit(); inline = this.Emitter.Output.ToString(); inline = inline.Replace("[[0]]", "{0}"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; this.Emitter.Output = oldBuilder; int[] range = null; if (thisIndex > -1) { range = new[] { thisIndex, thisIndex + thisArg.Length }; } if (resolveResult is InvocationResolveResult) { this.PushWriter(inline, null, thisArg, range); } else { if (member != null && member.Member is IMethod) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), oldInline, (IMethod)member.Member, targetrr).EmitFunctionReference(); } else if (member != null && member.Member is IField && inline.Contains("{0}")) { this.PushWriter(inline, null, thisArg, range); } else if (InlineArgumentsBlock.FormatArgRegex.IsMatch(inline)) { this.PushWriter(inline, null, thisArg, range); } else { this.Write(inline); } } return; } if (member != null && member.Member.SymbolKind == SymbolKind.Field && this.Emitter.IsMemberConst(member.Member) && this.Emitter.IsInlineConst(member.Member)) { var parentExpression = memberReferenceExpression.Parent as MemberReferenceExpression; bool wrap = false; if (parentExpression != null) { var ii = this.Emitter.GetInlineCode(parentExpression); if (string.IsNullOrEmpty(ii.Item3)) { wrap = true; this.WriteOpenParentheses(); } } this.WriteScript(Bridge.Translator.Emitter.ConvertConstant(member.ConstantValue, memberReferenceExpression, this.Emitter)); if (wrap) { this.WriteCloseParentheses(); } } else if (hasInline && member.Member.IsStatic) { if (resolveResult is InvocationResolveResult) { this.PushWriter(inline); } else { if (member != null && member.Member is IMethod) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline, (IMethod)member.Member, targetrr).EmitFunctionReference(); } else { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline).Emit(); } } } else { if (member != null && member.IsCompileTimeConstant && member.Member.DeclaringType.Kind == TypeKind.Enum) { var typeDef = member.Member.DeclaringType as ITypeDefinition; if (typeDef != null) { var enumMode = Helpers.EnumEmitMode(typeDef); if ((this.Emitter.Validator.IsExternalType(typeDef) && enumMode == -1) || enumMode == 2) { this.WriteScript(member.ConstantValue); return; } if (enumMode >= 3 && enumMode < 7) { string enumStringName = this.Emitter.GetEntityName(member.Member); this.WriteScript(enumStringName); return; } } } if (resolveResult is TypeResolveResult) { TypeResolveResult typeResolveResult = (TypeResolveResult)resolveResult; this.Write(BridgeTypes.ToJsName(typeResolveResult.Type, this.Emitter)); return; } else if (member != null && member.Member is IMethod && !(member is InvocationResolveResult) && !( memberReferenceExpression.Parent is InvocationExpression && memberReferenceExpression.NextSibling != null && memberReferenceExpression.NextSibling.Role is TokenRole && ((TokenRole)memberReferenceExpression.NextSibling.Role).Token == "(" ) ) { if (!string.IsNullOrEmpty(inline)) { if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline, (IMethod)member.Member, targetrr).EmitFunctionReference(); } else if (resolveResult is InvocationResolveResult || (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment)) { this.PushWriter(inline); } else { this.Write(inline); } } else { var resolvedMethod = (IMethod)member.Member; bool isStatic = resolvedMethod != null && resolvedMethod.IsStatic; var isExtensionMethod = resolvedMethod.IsExtensionMethod; this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (!isStatic) { this.Write(isExtensionMethod ? JS.Funcs.BRIDGE_BIND_SCOPE : JS.Funcs.BRIDGE_CACHE_BIND); this.WriteOpenParentheses(); if (memberReferenceExpression.Target is BaseReferenceExpression) { this.WriteThis(); } else { interfaceTempVar = this.WriteTarget(resolveResult, isInterfaceMember, memberTargetrr, targetrr, false); } this.Write(", "); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; if (isExtensionMethod) { this.Write(BridgeTypes.ToJsName(resolvedMethod.DeclaringType, this.Emitter)); } else { this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } if (interfaceTempVar != null) { this.Write(interfaceTempVar); } else { this.WriteSimpleTarget(resolveResult); } if (isConstTarget) { this.Write(")"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; } if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar, member, false); } else { this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation)); } if (!isStatic) { this.Write(")"); } } return; } else { bool isProperty = false; if (member != null && member.Member.SymbolKind == SymbolKind.Property && (member.Member.DeclaringTypeDefinition == null || !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition))) { isProperty = true; bool writeTargetVar = false; if (this.Emitter.IsAssignment && this.Emitter.AssignmentType != AssignmentOperatorType.Assign) { writeTargetVar = true; } else if (this.Emitter.IsUnaryAccessor) { writeTargetVar = true; isStatement = memberReferenceExpression.Parent is UnaryOperatorExpression && memberReferenceExpression.Parent.Parent is ExpressionStatement; if (NullableType.IsNullable(member.Type)) { isStatement = false; } if (!isStatement) { this.WriteOpenParentheses(); } } if (writeTargetVar) { bool isField = memberTargetrr != null && memberTargetrr.Member is IField && (memberTargetrr.TargetResult is ThisResolveResult || memberTargetrr.TargetResult is LocalResolveResult); if (!(targetrr is ThisResolveResult || targetrr is TypeResolveResult || targetrr is LocalResolveResult || isField)) { targetVar = this.GetTempVarName(); this.Write(targetVar); this.Write(" = "); } } } if (isProperty && this.Emitter.IsUnaryAccessor && !isStatement && targetVar == null) { valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); } this.Emitter.IsAssignment = false; this.Emitter.IsUnaryAccessor = false; if (isConstTarget) { this.Write("("); } if (targetVar == null && isInterfaceMember) { interfaceTempVar = this.WriteTarget(resolveResult, isInterfaceMember, memberTargetrr, targetrr, true); } else { this.WriteSimpleTarget(resolveResult); } if (member != null && targetrr != null && targetrr.Type.Kind == TypeKind.Delegate && (member.Member.Name == "Invoke")) { var method = member.Member as IMethod; if (!(method != null && method.IsExtensionMethod)) { return; } } if (isConstTarget) { this.Write(")"); } this.Emitter.IsAssignment = oldIsAssignment; this.Emitter.IsUnaryAccessor = oldUnary; if (targetVar != null) { if (this.Emitter.IsUnaryAccessor && !isStatement) { this.WriteComma(false); valueVar = this.GetTempVarName(); this.Write(valueVar); this.Write(" = "); this.Write(targetVar); } else { this.WriteSemiColon(); this.WriteNewLine(); this.Write(targetVar); } } } var targetResolveResult = targetrr as MemberResolveResult; if (targetResolveResult == null || this.Emitter.IsGlobalTarget(targetResolveResult.Member) == null) { if (isRefArg) { this.WriteComma(); } else if (!isInterfaceMember && !this.NoTarget) { this.WriteDot(); } } if (member == null) { if (targetrr != null && targetrr.Type.Kind == TypeKind.Dynamic) { this.Write(memberReferenceExpression.MemberName); } else { this.Write(memberReferenceExpression.MemberName.ToLowerCamelCase()); } } else if (!string.IsNullOrEmpty(inline)) { if (!(resolveResult is InvocationResolveResult) && member != null && member.Member is IMethod) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, memberReferenceExpression, resolveResult), inline, (IMethod)member.Member, targetrr).EmitFunctionReference(); } else if (resolveResult is InvocationResolveResult || (member.Member.SymbolKind == SymbolKind.Property && this.Emitter.IsAssignment)) { this.PushWriter(inline); } else { this.Write(inline); } } else if (member.Member.SymbolKind == SymbolKind.Property && (member.Member.DeclaringTypeDefinition == null || (!this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition) || member.Member.IsStatic))) { if (member.Member is IProperty && targetrr != null && targetrr.Type.GetDefinition() != null && this.Emitter.Validator.IsObjectLiteral(targetrr.Type.GetDefinition()) && !this.Emitter.Validator.IsObjectLiteral(member.Member.DeclaringTypeDefinition)) { this.Write(this.Emitter.GetLiteralEntityName(member.Member)); } else { if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false); } else { var name = OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation); var property = (IProperty)member.Member; var proto = member.IsVirtualCall || property.IsVirtual || property.IsOverride; if (this.MemberReferenceExpression.Target is BaseReferenceExpression && !property.IsIndexer && proto) { var alias = BridgeTypes.ToJsName(member.Member.DeclaringType, this.Emitter, isAlias: true); if (alias.StartsWith("\"")) { alias = alias.Insert(1, "$"); name = alias + "+\"$" + name + "\""; this.WriteIdentifier(name, false); } else { name = "$" + alias + "$" + name; this.WriteIdentifier(name); } } else { this.WriteIdentifier(name); } } } } else if (member.Member.SymbolKind == SymbolKind.Field) { bool isConst = this.Emitter.IsMemberConst(member.Member); if (isConst && this.Emitter.IsInlineConst(member.Member)) { this.WriteScript(Bridge.Translator.Emitter.ConvertConstant(member.ConstantValue, memberReferenceExpression, this.Emitter)); } else { if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false); } else { var fieldName = OverloadsCollection.Create(this.Emitter, member.Member).GetOverloadName(!nativeImplementation); if (isRefArg) { this.WriteScript(fieldName); } else { this.WriteIdentifier(fieldName); } } } } else if (resolveResult is InvocationResolveResult) { InvocationResolveResult invocationResult = (InvocationResolveResult)resolveResult; CSharpInvocationResolveResult cInvocationResult = resolveResult as CSharpInvocationResolveResult; var expresssionMember = expressionResolveResult as MemberResolveResult; if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false); } else if (expresssionMember != null && cInvocationResult != null && cInvocationResult.IsDelegateInvocation && invocationResult.Member != expresssionMember.Member) { this.Write(OverloadsCollection.Create(this.Emitter, expresssionMember.Member).GetOverloadName(!nativeImplementation)); } else { this.Write(OverloadsCollection.Create(this.Emitter, invocationResult.Member).GetOverloadName(!nativeImplementation)); } } else if (member.Member is IEvent) { if (this.Emitter.IsAssignment && (this.Emitter.AssignmentType == AssignmentOperatorType.Add || this.Emitter.AssignmentType == AssignmentOperatorType.Subtract)) { if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, this.Emitter.AssignmentType == AssignmentOperatorType.Subtract, Helpers.GetAddOrRemove(this.Emitter.AssignmentType == AssignmentOperatorType.Add)); } else { this.Write(Helpers.GetEventRef(member.Member, this.Emitter, this.Emitter.AssignmentType != AssignmentOperatorType.Add, ignoreInterface: !nativeImplementation)); } this.WriteOpenParentheses(); } else { if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false); } else { this.Write(this.Emitter.GetEntityName(member.Member)); } } } else { if (isInterfaceMember) { this.WriteInterfaceMember(interfaceTempVar ?? targetVar, member, false); } else { this.Write(this.Emitter.GetEntityName(member.Member)); } } Helpers.CheckValueTypeClone(resolveResult, memberReferenceExpression, this, pos); } }
ResolveResult CreateResult(ResolveResult targetResolveResult, List<LookupGroup> lookupGroups, string name, IList<IType> typeArguments) { // Remove all hidden groups lookupGroups.RemoveAll(g => g.AllHidden); if (lookupGroups.Count == 0) { // No members found return new UnknownMemberResolveResult(targetResolveResult.Type, name, typeArguments); } if (lookupGroups.Any(g => !g.MethodsAreHidden && g.Methods.Count > 0)) { // If there are methods, make a MethodGroupResolveResult. // Note that a conflict between a member and a method (possible with multiple interface inheritance) // is only a warning, not an error, and the C# compiler will prefer the method group. List<MethodListWithDeclaringType> methodLists = new List<MethodListWithDeclaringType>(); foreach (var lookupGroup in lookupGroups) { if (!lookupGroup.MethodsAreHidden && lookupGroup.Methods.Count > 0) { var methodListWithDeclType = new MethodListWithDeclaringType(lookupGroup.DeclaringType); foreach (var method in lookupGroup.Methods) { methodListWithDeclType.Add((IMethod)method); } methodLists.Add(methodListWithDeclType); } } return new MethodGroupResolveResult(targetResolveResult, name, methodLists, typeArguments); } // If there are ambiguities, report the most-derived result (last group) LookupGroup resultGroup = lookupGroups[lookupGroups.Count - 1]; if (resultGroup.NestedTypes != null && resultGroup.NestedTypes.Count > 0) { if (resultGroup.NestedTypes.Count > 1 || !resultGroup.NonMethodIsHidden || lookupGroups.Count > 1) return new AmbiguousTypeResolveResult(resultGroup.NestedTypes[0]); else return new TypeResolveResult(resultGroup.NestedTypes[0]); } if (resultGroup.NonMethod.IsStatic && targetResolveResult is ThisResolveResult) { targetResolveResult = new TypeResolveResult(targetResolveResult.Type); } if (lookupGroups.Count > 1) { return new AmbiguousMemberResolveResult(targetResolveResult, resultGroup.NonMethod); } else { if (isInEnumMemberInitializer) { IField field = resultGroup.NonMethod as IField; if (field != null && field.DeclaringTypeDefinition != null && field.DeclaringTypeDefinition.Kind == TypeKind.Enum) { return new MemberResolveResult( targetResolveResult, field, field.DeclaringTypeDefinition.EnumUnderlyingType, field.IsConst, field.ConstantValue); } } return new MemberResolveResult(targetResolveResult, resultGroup.NonMethod); } }
public AliasTypeResolveResult(string alias, TypeResolveResult underlyingResult) : base (underlyingResult.Type) { this.Alias = alias; }
public bool IsVariableReferenceWithSameType (ResolveResult rr, string identifier, out TypeResolveResult trr) { if (!(rr is MemberResolveResult || rr is LocalResolveResult)) { trr = null; return false; } trr = LookupSimpleNameOrTypeName (identifier, EmptyList<IType>.Instance, NameLookupMode.Type) as TypeResolveResult; return trr != null && trr.Type.Equals (rr.Type); }
private ResolveResult ResolveInvocation(ResolveResult target, ResolveResult[] arguments, string[] argumentNames, bool allowOptionalParameters) { // C# 4.0 spec: §7.6.5 if (target.Type.Kind == TypeKind.Dynamic) { return new DynamicInvocationResolveResult(target, DynamicInvocationType.Invocation, AddArgumentNamesIfNecessary(arguments, argumentNames)); } bool isDynamic = arguments.Any(a => a.Type.Kind == TypeKind.Dynamic); MethodGroupResolveResult mgrr = target as MethodGroupResolveResult; if (mgrr != null) { if (isDynamic) { // If we have dynamic arguments, we need to represent the invocation as a dynamic invocation if there is more than one applicable method. var or2 = CreateOverloadResolution(arguments, argumentNames, mgrr.TypeArguments.ToArray()); var applicableMethods = mgrr.MethodsGroupedByDeclaringType.SelectMany(m => m, (x, m) => new { x.DeclaringType, Method = m }).Where(x => OverloadResolution.IsApplicable(or2.AddCandidate(x.Method))).ToList(); if (applicableMethods.Count > 1) { ResolveResult actualTarget; if (applicableMethods.All(x => x.Method.IsStatic) && !(mgrr.TargetResult is TypeResolveResult)) actualTarget = new TypeResolveResult(mgrr.TargetType); else actualTarget = mgrr.TargetResult; var l = new List<MethodListWithDeclaringType>(); foreach (var m in applicableMethods) { if (l.Count == 0 || l[l.Count - 1].DeclaringType != m.DeclaringType) l.Add(new MethodListWithDeclaringType(m.DeclaringType)); l[l.Count - 1].Add(m.Method); } return new DynamicInvocationResolveResult(new MethodGroupResolveResult(actualTarget, mgrr.MethodName, l, mgrr.TypeArguments), DynamicInvocationType.Invocation, AddArgumentNamesIfNecessary(arguments, argumentNames)); } } OverloadResolution or = mgrr.PerformOverloadResolution(compilation, arguments, argumentNames, checkForOverflow: checkForOverflow, conversions: conversions, allowOptionalParameters: allowOptionalParameters); if (or.BestCandidate != null) { if (or.BestCandidate.IsStatic && !or.IsExtensionMethodInvocation && !(mgrr.TargetResult is TypeResolveResult)) return or.CreateResolveResult(new TypeResolveResult(mgrr.TargetType), returnTypeOverride: isDynamic ? SpecialType.Dynamic : null); else return or.CreateResolveResult(mgrr.TargetResult, returnTypeOverride: isDynamic ? SpecialType.Dynamic : null); } else { // No candidate found at all (not even an inapplicable one). // This can happen with empty method groups (as sometimes used with extension methods) return new UnknownMethodResolveResult( mgrr.TargetType, mgrr.MethodName, mgrr.TypeArguments, CreateParameters(arguments, argumentNames)); } } UnknownMemberResolveResult umrr = target as UnknownMemberResolveResult; if (umrr != null) { return new UnknownMethodResolveResult(umrr.TargetType, umrr.MemberName, umrr.TypeArguments, CreateParameters(arguments, argumentNames)); } UnknownIdentifierResolveResult uirr = target as UnknownIdentifierResolveResult; if (uirr != null && CurrentTypeDefinition != null) { return new UnknownMethodResolveResult(CurrentTypeDefinition, uirr.Identifier, EmptyList<IType>.Instance, CreateParameters(arguments, argumentNames)); } IMethod invokeMethod = target.Type.GetDelegateInvokeMethod(); if (invokeMethod != null) { OverloadResolution or = CreateOverloadResolution(arguments, argumentNames); or.AddCandidate(invokeMethod); return new CSharpInvocationResolveResult( target, invokeMethod, //invokeMethod.ReturnType.Resolve(context), or.GetArgumentsWithConversionsAndNames(), or.BestCandidateErrors, isExpandedForm: or.BestCandidateIsExpandedForm, isDelegateInvocation: true, argumentToParameterMap: or.GetArgumentToParameterMap(), returnTypeOverride: isDynamic ? SpecialType.Dynamic : null); } return ErrorResult; }