예제 #1
0
        void FindReferencesButtonClick(object sender, EventArgs e)
        {
            if (csharpTreeView.SelectedNode == null)
            {
                return;
            }

            SimpleProjectContent project = new SimpleProjectContent();
            var parsedFile = new TypeSystemConvertVisitor(project, "dummy.cs").Convert(compilationUnit);

            project.UpdateProjectContent(null, parsedFile);

            List <ITypeResolveContext> projects = new List <ITypeResolveContext>();

            projects.Add(project);
            projects.AddRange(builtInLibs.Value);

            using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
                CSharpResolver resolver = new CSharpResolver(context);

                AstNode node = (AstNode)csharpTreeView.SelectedNode.Tag;
                IResolveVisitorNavigator navigator = new NodeListResolveVisitorNavigator(new[] { node });
                ResolveVisitor           visitor   = new ResolveVisitor(resolver, parsedFile, navigator);
                visitor.Scan(compilationUnit);
                IEntity             entity;
                MemberResolveResult mrr = visitor.GetResolveResult(node) as MemberResolveResult;
                TypeResolveResult   trr = visitor.GetResolveResult(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) {
                    referenceCount++;
                };

                var searchScopes = fr.GetSearchScopes(entity);
                navigator = new CompositeResolveVisitorNavigator(searchScopes.Select(s => s.GetNavigator(callback)).ToArray());
                visitor   = new ResolveVisitor(resolver, parsedFile, navigator);
                visitor.Scan(compilationUnit);

                csharpTreeView.BeginUpdate();
                ShowResolveResultsInTree(csharpTreeView.Nodes, visitor);
                csharpTreeView.EndUpdate();

                MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName);
            }
        }
예제 #2
0
		public static ResolveResult Resolve(ICompilation compilation, CSharpParsedFile parsedFile, CompilationUnit cu, TextLocation location,
		                                    CancellationToken cancellationToken = default(CancellationToken))
		{
			AstNode node = cu.GetNodeAt(location);
			if (node == null)
				return null;
			AstNode resolvableNode;
			if (node is AstType) {
				resolvableNode = node;
				if (resolvableNode.Parent is ComposedType) {
					while (resolvableNode.Parent is ComposedType)
						resolvableNode = resolvableNode.Parent;
					//node is preffered over the resolvable node. Which shouldn't be done in the case of nullables, arrays etc.
					node = resolvableNode;
				}
			} else if (node is Identifier) {
				resolvableNode = node.Parent;
			} else if (node.NodeType == NodeType.Token) {
				if (node.Parent is ConstructorInitializer) {
					resolvableNode = node.Parent;
				} else {
					return null;
				}
			} else {
				// don't resolve arbitrary nodes - we don't want to show tooltips for everything
				return null;
			}
			
			if (resolvableNode != null && resolvableNode.Parent is ObjectCreateExpression) {
				resolvableNode = resolvableNode.Parent;
			}
			
			InvocationExpression parentInvocation = null;
			if ((resolvableNode is IdentifierExpression || resolvableNode is MemberReferenceExpression || resolvableNode is PointerReferenceExpression)) {
				// we also need to resolve the invocation
				parentInvocation = resolvableNode.Parent as InvocationExpression;
			}
			
			IResolveVisitorNavigator navigator;
			if (parentInvocation != null)
				navigator = new NodeListResolveVisitorNavigator(new[] { resolvableNode, parentInvocation });
			else
				navigator = new NodeListResolveVisitorNavigator(new[] { resolvableNode });
			
			CSharpResolver resolver = new CSharpResolver(compilation);
			ResolveVisitor v = new ResolveVisitor(resolver, parsedFile, navigator);
			v.Scan(cu);
			
			// Prefer the RR from the token itself, if it was assigned a ResolveResult
			// (this can happen with the identifiers in various nodes such as catch clauses or foreach statements)
			ResolveResult rr = v.GetResolveResult(node) ?? v.GetResolveResult(resolvableNode);
			if (rr is MethodGroupResolveResult && parentInvocation != null)
				return v.GetResolveResult(parentInvocation);
			else
				return rr;
		}
예제 #3
0
		string Convert(Expression expr)
		{
			ResolveVisitor rv = new ResolveVisitor(resolver, null);
			rv.Scan(expr);
			var codeExpr = (CodeExpression)convertVisitor.Convert(expr, rv);
			StringWriter writer = new StringWriter();
			writer.NewLine = " ";
			new CSharpCodeProvider().GenerateCodeFromExpression(codeExpr, writer, new CodeGeneratorOptions { IndentString = " " });
			return Regex.Replace(writer.ToString(), @"\s+", " ");
		}
예제 #4
0
		/// <summary>
		/// Creates a new C# AST resolver.
		/// Use this overload if you are resolving code snippets (not necessarily complete files).
		/// </summary>
		/// <param name="resolver">The resolver state at the root node (to be more precise: outside the root node).</param>
		/// <param name="rootNode">The root node of the resolved tree.</param>
		/// <param name="parsedFile">The parsed file for the nodes being resolved. This parameter is used only
		/// when the root node is on the type level; it is not necessary when an expression is passed.
		/// This parameter may be null.</param>
		public CppAstResolver(CppResolver resolver, AstNode rootNode, CppParsedFile parsedFile = null)
		{
			if (resolver == null)
				throw new ArgumentNullException("resolver");
			if (rootNode == null)
				throw new ArgumentNullException("rootNode");
			this.initialResolverState = resolver;
			this.rootNode = rootNode;
			this.parsedFile = parsedFile;
			this.resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile);
		}
        public DefiniteAssignmentAnalysis(Statement rootStatement, ResolveVisitor resolveVisitor)
        {
            if (rootStatement == null)
            {
                throw new ArgumentNullException("rootStatement");
            }
            if (resolveVisitor == null)
            {
                throw new ArgumentNullException("resolveVisitor");
            }
            this.resolveVisitor    = resolveVisitor;
            this.cancellationToken = resolveVisitor.CancellationToken;
            visitor.analysis       = this;
            if (resolveVisitor.TypeResolveContext is MinimalResolveContext)
            {
                cfgBuilder.EvaluateOnlyPrimitiveConstants = true;
            }
            allNodes.AddRange(cfgBuilder.BuildControlFlowGraph(rootStatement, resolveVisitor).Cast <DefiniteAssignmentNode>());
            for (int i = 0; i < allNodes.Count; i++)
            {
                DefiniteAssignmentNode node = allNodes[i];
                node.Index = i;                 // assign numbers to the nodes
                if (node.Type == ControlFlowNodeType.StartNode || node.Type == ControlFlowNodeType.BetweenStatements)
                {
                    // Anonymous methods have separate control flow graphs, but we also need to analyze those.
                    // Iterate backwards so that anonymous methods are inserted in the correct order
                    for (AstNode child = node.NextStatement.LastChild; child != null; child = child.PrevSibling)
                    {
                        InsertAnonymousMethods(i + 1, child);
                    }
                }
                // Now register the node in the dictionaries:
                if (node.Type == ControlFlowNodeType.StartNode || node.Type == ControlFlowNodeType.BetweenStatements)
                {
                    beginNodeDict.Add(node.NextStatement, node);
                }
                if (node.Type == ControlFlowNodeType.BetweenStatements || node.Type == ControlFlowNodeType.EndNode)
                {
                    endNodeDict.Add(node.PreviousStatement, node);
                }
                if (node.Type == ControlFlowNodeType.LoopCondition)
                {
                    conditionNodeDict.Add(node.NextStatement, node);
                }
            }
            // Verify that we created nodes for all statements:
            Debug.Assert(!rootStatement.DescendantsAndSelf.OfType <Statement>().Except(allNodes.Select(n => n.NextStatement)).Any());
            // Verify that we put all nodes into the dictionaries:
            Debug.Assert(rootStatement.DescendantsAndSelf.OfType <Statement>().All(stmt => beginNodeDict.ContainsKey(stmt)));
            Debug.Assert(rootStatement.DescendantsAndSelf.OfType <Statement>().All(stmt => endNodeDict.ContainsKey(stmt)));

            this.analyzedRangeStart = 0;
            this.analyzedRangeEnd   = allNodes.Count - 1;
        }
예제 #6
0
		/// <summary>
		/// Creates a new C# AST resolver.
		/// Use this overload if you are resolving within a complete C# file.
		/// </summary>
		/// <param name="compilation">The current compilation.</param>
		/// <param name="compilationUnit">The compilation unit corresponding to the specified parsed file.</param>
		/// <param name="parsedFile">
		/// Optional: Result of the <see cref="TypeSystemConvertVisitor"/> for the file being resolved.
		/// <para>
		/// This is used for setting up the context on the resolver. The parsed file must be registered in the compilation.
		/// </para>
		/// <para>
		/// When a parsedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
		/// member declarations in the AST with members in the type system.
		/// When no parsedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
		/// member's signature in the AST with the signature in the type system.
		/// </para>
		/// </param>
		public CSharpAstResolver(ICompilation compilation, CompilationUnit compilationUnit, CSharpParsedFile parsedFile = null)
		{
			if (compilation == null)
				throw new ArgumentNullException("compilation");
			if (compilationUnit == null)
				throw new ArgumentNullException("compilationUnit");
			this.initialResolverState = new CSharpResolver(compilation);
			this.rootNode = compilationUnit;
			this.parsedFile = parsedFile;
			this.resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile);
		}
예제 #7
0
		/// <summary>
		/// Creates a new C# AST resolver.
		/// Use this overload if you are resolving within a complete C# file.
		/// </summary>
		/// <param name="compilation">The current compilation.</param>
		/// <param name="syntaxTree">The syntax tree to be resolved.</param>
		/// <param name="unresolvedFile">
		/// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
		/// <para>
		/// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
		/// </para>
		/// <para>
		/// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
		/// member declarations in the AST with members in the type system.
		/// When no unresolvedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
		/// member's signature in the AST with the signature in the type system.
		/// </para>
		/// </param>
		public CSharpAstResolver(ICompilation compilation, SyntaxTree syntaxTree, CSharpUnresolvedFile unresolvedFile = null)
		{
			if (compilation == null)
				throw new ArgumentNullException("compilation");
			if (syntaxTree == null)
				throw new ArgumentNullException("syntaxTree");
			this.initialResolverState = new CSharpResolver(compilation);
			this.rootNode = syntaxTree;
			this.unresolvedFile = unresolvedFile;
			this.resolveVisitor = new ResolveVisitor(initialResolverState, unresolvedFile);
		}
        /// <summary>
        /// Creates a new BVE5 AST resolver.
        /// Use this overload if you are resolving within a complete BVE5 file.
        /// </summary>
        /// <param name="compilation">The current compilation.</param>
        /// <param name="syntaxTree">The syntax tree to be resolved.</param>
        /// <param name="unresolvedFile">
        /// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
        /// <para>
        /// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
        /// </para>
        /// <para>
        /// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
        /// member declarations in the AST with members in the type system.
        /// When no unresolvedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
        /// member's signature in the AST with the signature in the type system.
        /// </para>
        /// </param>
        public BVE5AstResolver(ICompilation compilation, SyntaxTree syntaxTree, BVE5UnresolvedFile unresolvedFile = null)
        {
            if(compilation == null)
                throw new ArgumentNullException("compilation");

            if(syntaxTree == null)
                throw new ArgumentNullException("syntaxTree");

            initial_resolver_state = new BVE5Resolver(compilation);
            root_node = syntaxTree;
            unresolved_file = unresolvedFile;
            resolve_visitor = new ResolveVisitor(initial_resolver_state, unresolvedFile);
        }
        /// <summary>
        /// Creates a new BVE5 AST resolver.
        /// Use this overload if you are resolving within a complete BVE5 file.
        /// </summary>
        /// <param name="compilation">The current compilation.</param>
        /// <param name="syntaxTree">The syntax tree to be resolved.</param>
        /// <param name="unresolvedFile">
        /// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
        /// <para>
        /// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
        /// </para>
        /// <para>
        /// When the unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
        /// member declarations in the AST with members in the type system.
        /// When no unresolvedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
        /// member's signature in the AST with the signature in the type system.
        /// </para>
        /// </param>
        public BVE5AstResolver(BVE5Compilation compilation, SyntaxTree syntaxTree, BVE5UnresolvedFile unresolvedFile = null)
        {
            if(compilation == null)
                throw new ArgumentNullException("compilation");

            if(syntaxTree == null)
                throw new ArgumentNullException("syntaxTree");

            initial_resolver_state = new BVE5Resolver(compilation);
            root_node = syntaxTree;
            unresolved_file = unresolvedFile;
            resolve_visitor = new ResolveVisitor(initial_resolver_state, unresolvedFile, FileKindHelper.GetTypeNameFromFileKind(syntaxTree.Kind));
        }
예제 #10
0
        string Convert(Expression expr)
        {
            ResolveVisitor rv = new ResolveVisitor(resolver, null);

            rv.Scan(expr);
            var          codeExpr = (CodeExpression)convertVisitor.Convert(expr, rv);
            StringWriter writer   = new StringWriter();

            writer.NewLine = " ";
            new CSharpCodeProvider().GenerateCodeFromExpression(codeExpr, writer, new CodeGeneratorOptions {
                IndentString = " "
            });
            return(Regex.Replace(writer.ToString(), @"\s+", " "));
        }
예제 #11
0
 /// <summary>
 /// Creates a new C# AST resolver.
 /// Use this overload if you are resolving code snippets (not necessarily complete files).
 /// </summary>
 /// <param name="resolver">The resolver state at the root node (to be more precise: outside the root node).</param>
 /// <param name="rootNode">The root node of the resolved tree.</param>
 /// <param name="parsedFile">The parsed file for the nodes being resolved. This parameter is used only
 /// when the root node is on the type level; it is not necessary when an expression is passed.
 /// This parameter may be null.</param>
 public CppAstResolver(CppResolver resolver, AstNode rootNode, CppParsedFile parsedFile = null)
 {
     if (resolver == null)
     {
         throw new ArgumentNullException("resolver");
     }
     if (rootNode == null)
     {
         throw new ArgumentNullException("rootNode");
     }
     this.initialResolverState = resolver;
     this.rootNode             = rootNode;
     this.parsedFile           = parsedFile;
     this.resolveVisitor       = new ResolveVisitor(initialResolverState, parsedFile);
 }
 /// <summary>
 /// Creates a new C# AST resolver.
 /// Use this overload if you are resolving code snippets (not necessarily complete files).
 /// </summary>
 /// <param name="resolver">The resolver state at the root node (to be more precise: just outside the root node).</param>
 /// <param name="rootNode">The root node of the tree to be resolved.</param>
 /// <param name="unresolvedFile">
 /// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
 /// <para>
 /// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
 /// </para>
 /// <para>
 /// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
 /// member declarations in the AST with members in the type system.
 /// When no unresolvedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
 /// member's signature in the AST with the signature in the type system.
 /// </para>
 /// </param>
 public CSharpAstResolver(CSharpResolver resolver, AstNode rootNode, CSharpUnresolvedFile unresolvedFile = null)
 {
     if (resolver == null)
     {
         throw new ArgumentNullException("resolver");
     }
     if (rootNode == null)
     {
         throw new ArgumentNullException("rootNode");
     }
     this.initialResolverState = resolver;
     this.rootNode             = rootNode;
     this.unresolvedFile       = unresolvedFile;
     this.resolveVisitor       = new ResolveVisitor(initialResolverState, unresolvedFile);
 }
예제 #13
0
        public HlslVisitor(BlockStatement block, CustomAttribute attr, ResolveVisitor resolver, DecompilerContext ctx)
            : this()
        {
            _attr = attr;
            _resolver = resolver;
            _resolver.Scan(block);

            var trans1 = new ReplaceMethodCallsWithOperators(ctx);
            var trans2 = new RenameLocals();
            ((IAstTransform)trans1).Run(block);
            trans2.Run(block);

            Result = block.AcceptVisitor(this, 0).ToString();
            Result += Environment.NewLine;
        }
 /// <summary>
 /// Creates a new C# AST resolver.
 /// Use this overload if you are resolving within a complete C# file.
 /// </summary>
 /// <param name="compilation">The current compilation.</param>
 /// <param name="syntaxTree">The syntax tree to be resolved.</param>
 /// <param name="unresolvedFile">
 /// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
 /// <para>
 /// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
 /// </para>
 /// <para>
 /// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
 /// member declarations in the AST with members in the type system.
 /// When no unresolvedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
 /// member's signature in the AST with the signature in the type system.
 /// </para>
 /// </param>
 public CSharpAstResolver(ICompilation compilation, SyntaxTree syntaxTree, CSharpUnresolvedFile unresolvedFile = null)
 {
     if (compilation == null)
     {
         throw new ArgumentNullException("compilation");
     }
     if (syntaxTree == null)
     {
         throw new ArgumentNullException("syntaxTree");
     }
     this.initialResolverState = new CSharpResolver(compilation);
     this.rootNode             = syntaxTree;
     this.unresolvedFile       = unresolvedFile;
     this.resolveVisitor       = new ResolveVisitor(initialResolverState, unresolvedFile);
 }
예제 #15
0
        public HlslVisitor(BlockStatement block, CustomAttribute attr, ResolveVisitor resolver, DecompilerContext ctx)
            : this()
        {
            _attr     = attr;
            _resolver = resolver;
            _resolver.Scan(block);

            var trans1 = new ReplaceMethodCallsWithOperators(ctx);
            var trans2 = new RenameLocals();

            ((IAstTransform)trans1).Run(block);
            trans2.Run(block);

            Result  = block.AcceptVisitor(this, 0).ToString();
            Result += Environment.NewLine;
        }
예제 #16
0
        public IList <ControlFlowNode> BuildControlFlowGraph(Statement statement, ResolveVisitor resolveVisitor)
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }
            if (resolveVisitor == null)
            {
                throw new ArgumentNullException("resolveVisitor");
            }

            NodeCreationVisitor nodeCreationVisitor = new NodeCreationVisitor();

            nodeCreationVisitor.builder = this;
            try {
                this.nodes          = new List <ControlFlowNode>();
                this.labels         = new Dictionary <string, ControlFlowNode>();
                this.gotoStatements = new List <ControlFlowNode>();
                this.rootStatement  = statement;
                this.resolveVisitor = resolveVisitor;
                ControlFlowNode entryPoint = CreateStartNode(statement);
                statement.AcceptVisitor(nodeCreationVisitor, entryPoint);

                // Resolve goto statements:
                foreach (ControlFlowNode gotoStmt in gotoStatements)
                {
                    string          label = ((GotoStatement)gotoStmt.NextStatement).Label;
                    ControlFlowNode labelNode;
                    if (labels.TryGetValue(label, out labelNode))
                    {
                        nodeCreationVisitor.Connect(gotoStmt, labelNode, ControlFlowEdgeType.Jump);
                    }
                }

                AnnotateLeaveEdgesWithTryFinallyBlocks();

                return(nodes);
            } finally {
                this.nodes          = null;
                this.labels         = null;
                this.gotoStatements = null;
                this.rootStatement  = null;
                this.resolveVisitor = null;
            }
        }
예제 #17
0
 /// <summary>
 /// Creates a new C# AST resolver.
 /// Use this overload if you are resolving within a complete C# file.
 /// </summary>
 /// <param name="compilation">The current compilation.</param>
 /// <param name="parsedFile">
 /// Result of the <see cref="TypeSystemConvertVisitor"/> for the file being passed. This is used for setting up the context on the resolver. The parsed file must be registered in the compilation.
 /// </param>
 /// <param name="compilationUnit">The compilation unit corresponding to the specified parsed file.</param>
 public CppAstResolver(ICompilation compilation, CompilationUnit compilationUnit, CppParsedFile parsedFile)
 {
     if (compilation == null)
     {
         throw new ArgumentNullException("compilation");
     }
     if (parsedFile == null)
     {
         throw new ArgumentNullException("parsedFile");
     }
     if (compilationUnit == null)
     {
         throw new ArgumentNullException("compilationUnit");
     }
     this.initialResolverState = new CppResolver(compilation);
     this.rootNode             = compilationUnit;
     this.parsedFile           = parsedFile;
     this.resolveVisitor       = new ResolveVisitor(initialResolverState, parsedFile);
 }
예제 #18
0
 void ShowResolveResultsInTree(TreeNodeCollection c, ResolveVisitor v)
 {
     foreach (TreeNode t in c)
     {
         AstNode node = t.Tag as AstNode;
         if (node != null)
         {
             ResolveResult rr = v.GetResolveResult(node);
             if (rr != null)
             {
                 t.Text = GetNodeTitle(node) + " " + rr.ToString();
             }
             else
             {
                 t.Text = GetNodeTitle(node);
             }
         }
         ShowResolveResultsInTree(t.Nodes, v);
     }
 }
예제 #19
0
        /// <summary>
        /// Public translation interface.
        /// Translates the given method to HLSL
        /// </summary>
        /// <param name="s">Shader type definition.</param>
        /// <param name="m">A method representing a shader to translate.</param>
        /// <param name="attr">The shader type as attribute (either FragmentShaderAttribute or VertexShaderAttribute</param>
        /// <param name="type">The shader type as ShaderType</param>
        /// <returns>The translated GLSL shader source</returns>
        public FunctionDescription Transform(TypeDefinition s, MethodDefinition m, CustomAttribute attr,
                                             ShaderType type)
        {
            if (s == null)
            {
                throw new ArgumentNullException("s");
            }

            if (m == null)
            {
                throw new ArgumentNullException("m");
            }

            if (attr == null)
            {
                throw new ArgumentNullException("attr");
            }

            var sbase = s.BaseType.Resolve();

            while (sbase.MetadataToken.ToInt32() != typeof(Shader).MetadataToken)
            {
                sbase = sbase.BaseType.Resolve();
            }

            var dctx = new DecompilerContext(s.Module)
            {
                CurrentType       = s,
                CurrentMethod     = m,
                CancellationToken = CancellationToken.None
            };
            var d = AstMethodBodyBuilder.CreateMethodBody(m, dctx);

            //var ctx = new CecilTypeResolveContext(sbase.Module);

            var loader   = new CecilLoader();
            var mscorlib = loader.LoadAssemblyFile(typeof(object).Assembly.Location);
            var slsharp  = loader.LoadAssembly(sbase.Module.Assembly);
            var project  = loader.LoadAssembly(s.Module.Assembly);

            var ctx      = new CompositeTypeResolveContext(new[] { project, slsharp, mscorlib });
            var resolver = new CSharpResolver(ctx, CancellationToken.None)
            {
                UsingScope = new UsingScope(project)
            };

            /*
             * foreach (var v in m.Body.Variables)
             * {
             *  resolver.AddVariable(v.VariableType, null, v.Name)
             * }*/

            //resolver.AddVariable()

            //resolver.LocalVariables = m.Body.Variables;


            // TODO: need a more sane way to get the correct class + member
            var ss = ctx.GetAllTypes().First(c => c.FullName == s.FullName);

            resolver.CurrentTypeDefinition = ss;
            resolver.CurrentMember         = ss.Methods.First(n => SameMethod(m, n, ctx));

            var rv = new ResolveVisitor(resolver, new ParsedFile("memory", resolver.UsingScope), null);

            var glsl = new HlslVisitor(d, attr, rv, dctx);

            _functions.UnionWith(glsl.Functions);

            var entry = (bool)attr.ConstructorArguments.FirstOrDefault().Value;
            var sig   = HlslVisitor.GetSignature(m);

            var code = glsl.Result;
            var desc = new FunctionDescription(Shader.GetMethodName(m), sig + code, entry, type);

            _dependencies.UnionWith(glsl.Dependencies);

            return(desc);
        }
예제 #20
0
        /// <summary>
        /// Public translation interface.
        /// Translates the given method to HLSL
        /// </summary>
        /// <param name="s">Shader type definition.</param>
        /// <param name="m">A method representing a shader to translate.</param>
        /// <param name="attr">The shader type as attribute (either FragmentShaderAttribute or VertexShaderAttribute</param>
        /// <param name="type">The shader type as ShaderType</param>
        /// <returns>The translated GLSL shader source</returns>
        public FunctionDescription Transform(TypeDefinition s, MethodDefinition m, CustomAttribute attr,
            ShaderType type)
        {
            if (s == null)
                throw new ArgumentNullException("s");

            if (m == null)
                throw new ArgumentNullException("m");

            if (attr == null)
                throw new ArgumentNullException("attr");

            var sbase = s.BaseType.Resolve();
            while (sbase.MetadataToken.ToInt32() != typeof(Shader).MetadataToken)
                sbase = sbase.BaseType.Resolve();

            var dctx = new DecompilerContext(s.Module)
            {
                CurrentType = s,
                CurrentMethod = m,
                CancellationToken = CancellationToken.None
            };
            var d = AstMethodBodyBuilder.CreateMethodBody(m, dctx);

            //var ctx = new CecilTypeResolveContext(sbase.Module);

            var loader = new CecilLoader();
            var mscorlib = loader.LoadAssemblyFile(typeof(object).Assembly.Location);
            var slsharp = loader.LoadAssembly(sbase.Module.Assembly);
            var project = loader.LoadAssembly(s.Module.Assembly);

            var ctx = new CompositeTypeResolveContext(new[] { project, slsharp, mscorlib });
            var resolver = new CSharpResolver(ctx, CancellationToken.None) {UsingScope = new UsingScope(project)};

            /*
            foreach (var v in m.Body.Variables)
            {
                resolver.AddVariable(v.VariableType, null, v.Name)
            }*/

            //resolver.AddVariable()

            //resolver.LocalVariables = m.Body.Variables;

            // TODO: need a more sane way to get the correct class + member
            var ss = ctx.GetAllTypes().First(c => c.FullName == s.FullName);
            resolver.CurrentTypeDefinition = ss;
            resolver.CurrentMember = ss.Methods.First(n => SameMethod(m, n, ctx));

            var rv = new ResolveVisitor(resolver, new ParsedFile("memory", resolver.UsingScope), null);

            var glsl = new HlslVisitor(d, attr, rv, dctx);

            _functions.UnionWith(glsl.Functions);

            var entry = (bool)attr.ConstructorArguments.FirstOrDefault().Value;
            var sig = HlslVisitor.GetSignature(m);

            var code = glsl.Result;
            var desc = new FunctionDescription(Shader.GetMethodName(m), sig + code, entry, type);

            _dependencies.UnionWith(glsl.Dependencies);

            return desc;
        }
        protected Tuple<ResolveResult, CSharpResolver> ResolveExpression(CSharpParsedFile file, AstNode expr, CompilationUnit unit)
        {
            if (expr == null)
                return null;
            AstNode resolveNode;
            if (expr is Expression || expr is AstType) {
                resolveNode = expr;
            } else if (expr is VariableDeclarationStatement) {
                resolveNode = ((VariableDeclarationStatement)expr).Type;
            } else {
                resolveNode = expr;
            }

            //			var newContent = ProjectContent.UpdateProjectContent (CSharpParsedFile, file);

            var csResolver = new CSharpResolver (ctx);

            var navigator = new NodeListResolveVisitorNavigator (new[] { resolveNode });
            var visitor = new ResolveVisitor (csResolver, CSharpParsedFile, navigator);

            visitor.Scan (unit);
            var state = visitor.GetResolverStateBefore (resolveNode);
            var result = visitor.GetResolveResult (resolveNode);
            return Tuple.Create (result, state);
        }
예제 #22
0
        IEnumerable<ICompletionData> MagicKeyCompletion(char completionChar, bool controlSpace)
        {
            switch (completionChar) {
            // Magic key completion
            case ':':
            case '.':
                if (IsInsideCommentOrString ())
                    return Enumerable.Empty<ICompletionData> ();
                var expr = GetExpressionBeforeCursor ();
                if (expr == null)
                    return null;
                // do not complete <number>. (but <number>.<number>.)
                if (expr.Item2 is PrimitiveExpression) {
                    var pexpr = (PrimitiveExpression)expr.Item2;
                    if (!(pexpr.Value is string || pexpr.Value is char) && !pexpr.LiteralValue.Contains ('.'))
                        return null;
                }

                var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3);

                if (resolveResult == null)
                    return null;
                if (expr.Item2 is AstType)
                    return CreateTypeAndNamespaceCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
                return CreateCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
            case '#':
                if (IsInsideCommentOrString ())
                    return null;
                return GetDirectiveCompletionData ();

            // XML doc completion
            case '<':
                if (IsInsideDocComment ())
                    return GetXmlDocumentationCompletionData ();
                if (controlSpace)
                    return DefaultControlSpaceItems ();
                return null;
            case '>':
                if (!IsInsideDocComment ())
                    return null;
                string lineText = document.GetText (document.GetLineByNumber (location.Line));
                int startIndex = Math.Min (location.Column - 1, lineText.Length - 1);

                while (startIndex >= 0 && lineText [startIndex] != '<') {
                    --startIndex;
                    if (lineText [startIndex] == '/') { // already closed.
                        startIndex = -1;
                        break;
                    }
                }

                if (startIndex >= 0) {
                    int endIndex = startIndex;
                    while (endIndex <= location.Column && endIndex < lineText.Length && !Char.IsWhiteSpace (lineText [endIndex])) {
                        endIndex++;
                    }
                    string tag = endIndex - startIndex - 1 > 0 ? lineText.Substring (startIndex + 1, endIndex - startIndex - 2) : null;
                    if (!string.IsNullOrEmpty (tag) && commentTags.IndexOf (tag) >= 0)
                        document.Insert (offset, "</" + tag + ">");
                }
                return null;

            // Parameter completion
            case '(':
                if (IsInsideCommentOrString ())
                    return null;
                var invoke = GetInvocationBeforeCursor (true);
                if (invoke == null)
                    return null;
                if (invoke.Item2 is TypeOfExpression)
                    return CreateTypeList ();
                var invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
                if (invocationResult == null)
                    return null;
                var methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
                if (methodGroup != null)
                    return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, 0, controlSpace);

                if (controlSpace)
                    return DefaultControlSpaceItems (invoke);

                return null;
            case '=':
                return controlSpace ? DefaultControlSpaceItems () : null;
            case ',':
                int cpos2;
                if (!GetParameterCompletionCommandOffset (out cpos2))
                    return null;
            //	completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2);
            //	int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1;
            //				return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter);
                break;

            // Completion on space:
            case ' ':
                if (IsInsideCommentOrString ())
                    return null;

                int tokenIndex = offset;
                string token = GetPreviousToken (ref tokenIndex, false);
                // check propose name, for context <variable name> <ctrl+space> (but only in control space context)
                //IType isAsType = null;
                var isAsExpression = GetExpressionAt (offset);
                if (controlSpace && isAsExpression != null && isAsExpression.Item2 is VariableDeclarationStatement && token != "new") {
                    var parent = isAsExpression.Item2 as VariableDeclarationStatement;
                    var proposeNameList = new CompletionDataWrapper (this);

                    foreach (var possibleName in GenerateNameProposals (parent.Type)) {
                        if (possibleName.Length > 0)
                            proposeNameList.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ()));
                    }

                    AutoSelect = false;
                    AutoCompleteEmptyMatch = false;
                    return proposeNameList.Result;
                }
            //				int tokenIndex = offset;
            //				string token = GetPreviousToken (ref tokenIndex, false);
            //				if (result.ExpressionContext == ExpressionContext.ObjectInitializer) {
            //					resolver = CreateResolver ();
            //					ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, resolver.Unit, Document.FileName, resolver.CallingType);
            //					IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType;
            //					if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ","))
            //						return CreateCtrlSpaceCompletionData (completionContext, result);
            //				}
                if (token == "=") {
                    int j = tokenIndex;
                    string prevToken = GetPreviousToken (ref j, false);
                    if (prevToken == "=" || prevToken == "+" || prevToken == "-") {
                        token = prevToken + token;
                        tokenIndex = j;
                    }
                }
                switch (token) {
                case "(":
                case ",":
                    int cpos;
                    if (!GetParameterCompletionCommandOffset (out cpos))
                        break;
                    int currentParameter = GetCurrentParameterIndex (cpos, 0) - 1;
                    if (currentParameter < 0)
                        return null;
                    invoke = GetInvocationBeforeCursor (token == "(");
                    if (invoke == null)
                        return null;
                    invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
                    if (invocationResult == null)
                        return null;
                    methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
                    if (methodGroup != null)
                        return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, currentParameter, controlSpace);
                    return null;
                case "=":
                case "==":
                    GetPreviousToken (ref tokenIndex, false);

                    var expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
                    if (expressionOrVariableDeclaration == null)
                        return null;

                    resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
                    if (resolveResult == null)
                        return null;
                    if (resolveResult.Item1.Type.Kind == TypeKind.Enum) {
                        var wrapper = new CompletionDataWrapper (this);
                        AddContextCompletion (wrapper, resolveResult.Item2, expressionOrVariableDeclaration.Item2);
                        AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
                        AutoCompleteEmptyMatch = false;
                        return wrapper.Result;
                    }
            //
            //					if (resolvedType.FullName == DomReturnType.Bool.FullName) {
            //						CompletionDataList completionList = new ProjectDomCompletionDataList ();
            //						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
            //						completionList.AutoCompleteEmptyMatch = false;
            //						cdc.Add ("true", "md-keyword");
            //						cdc.Add ("false", "md-keyword");
            //						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
            //						return completionList;
            //					}
            //					if (resolvedType.ClassType == ClassType.Delegate && token == "=") {
            //						CompletionDataList completionList = new ProjectDomCompletionDataList ();
            //						string parameterDefinition = AddDelegateHandlers (completionList, resolvedType);
            //						string varName = GetPreviousMemberReferenceExpression (tokenIndex);
            //						completionList.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType));
            //
            //						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
            //						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
            //						foreach (var data in completionList) {
            //							if (data is MemberCompletionData)
            //								((MemberCompletionData)data).IsDelegateExpected = true;
            //						}
            //						return completionList;
            //					}
                    return null;
                case "+=":
                case "-=":
                    GetPreviousToken (ref tokenIndex, false);

                    expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
                    if (expressionOrVariableDeclaration == null)
                        return null;

                    resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
                    if (resolveResult == null)
                        return null;

                    var mrr = resolveResult.Item1 as MemberResolveResult;
                    if (mrr != null) {
                        var evt = mrr.Member as IEvent;
                        if (evt == null)
                            return null;
                        var delegateType = evt.ReturnType;
                        if (delegateType.Kind != TypeKind.Delegate)
                            return null;

                        var wrapper = new CompletionDataWrapper (this);
                        if (currentType != null) {
            //							bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
                            foreach (var method in currentType.Methods) {
                                if (MatchDelegate (delegateType, method) /*&& method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) &&*/) {
                                    wrapper.AddMember (method);
            //									data.SetText (data.CompletionText + ";");
                                }
                            }
                        }
                        if (token == "+=") {
                            string parameterDefinition = AddDelegateHandlers (wrapper, delegateType);
                            string varName = GetPreviousMemberReferenceExpression (tokenIndex);
                            wrapper.Result.Add (factory.CreateEventCreationCompletionData (varName, delegateType, evt, parameterDefinition, currentMember, currentType));
                        }

                        return wrapper.Result;
                    }
                    return null;
                case ":":
                    if (currentMember == null) {
                        var wrapper = new CompletionDataWrapper (this);
                        AddTypesAndNamespaces (wrapper, GetState (), null, t => currentType != null ? !currentType.Equals (t) : true);
                        return wrapper.Result;
                    }
                    return null;
                }

                var keywordCompletion = HandleKeywordCompletion (tokenIndex, token);
                if (keywordCompletion == null && controlSpace)
                    goto default;
                return keywordCompletion;
            // Automatic completion
            default:
                if (IsInsideCommentOrString ())
                    return null;
                if (IsInLinqContext (offset)) {
                    tokenIndex = offset;
                    token = GetPreviousToken (ref tokenIndex, false); // token last typed
                    if (linqKeywords.Contains (token)) {
                        if (token == "from") // after from no auto code completion.
                            return null;
                        return DefaultControlSpaceItems ();
                    }
                    var dataList = new CompletionDataWrapper (this);
                    AddKeywords (dataList, linqKeywords);
                    return dataList.Result;
                }

                if (currentType != null && currentType.Kind == TypeKind.Enum)
                    return HandleEnumContext ();

                var contextList = new CompletionDataWrapper (this);
                var identifierStart = GetExpressionAtCursor ();
                if (identifierStart != null && identifierStart.Item2 is TypeParameterDeclaration)
                    return null;

                if (identifierStart != null && identifierStart.Item2 is VariableInitializer && location <= ((VariableInitializer)identifierStart.Item2).NameToken.EndLocation) {
                    return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null;
                }
                if (!(char.IsLetter (completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Item2 is ArrayInitializerExpression))) {
                    return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null;
                }
                char prevCh = offset > 2 ? document.GetCharAt (offset - 2) : ';';
                char nextCh = offset < document.TextLength ? document.GetCharAt (offset) : ' ';
                const string allowedChars = ";,[](){}+-*/%^?:&|~!<>=";
                if (!Char.IsWhiteSpace (nextCh) && allowedChars.IndexOf (nextCh) < 0)
                    return null;
                if (!(Char.IsWhiteSpace (prevCh) || allowedChars.IndexOf (prevCh) >= 0))
                    return null;
                // Do not pop up completion on identifier identifier (should be handled by keyword completion).
                tokenIndex = offset - 1;
                token = GetPreviousToken (ref tokenIndex, false);
                int prevTokenIndex = tokenIndex;
                var prevToken2 = GetPreviousToken (ref prevTokenIndex, false);
                if (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex)) && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) {
                    char last = token [token.Length - 1];
                    if (char.IsLetterOrDigit (last) || last == '_' || token == ">") {
                        return HandleKeywordCompletion (tokenIndex, token);
                    }
                }

                if (identifierStart == null)
                    return HandleAccessorContext () ?? DefaultControlSpaceItems ();

                CSharpResolver csResolver;
                AstNode n = identifierStart.Item2;
                // Handle foreach (type name _
                if (n is IdentifierExpression) {
                    var prev = n.GetPrevNode () as ForeachStatement;
                    if (prev != null && prev.InExpression.IsNull) {
                        if (controlSpace) {
                            contextList.AddCustom ("in");
                            return contextList.Result;
                        }
                        return null;
                    }
                }

                if (n is Identifier && n.Parent is ForeachStatement) {
                    if (controlSpace)
                        return DefaultControlSpaceItems ();
                    return null;
                }
                if (n is ArrayInitializerExpression) {
                    // check for new [] {...} expression -> no need to resolve the type there
                    var parent = n.Parent as ArrayCreateExpression;
                    if (parent != null && parent.Type.IsNull)
                        return DefaultControlSpaceItems ();

                    var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3);

                    var concreteNode = identifierStart.Item3.GetNodeAt<IdentifierExpression> (location);
                    // check if we're on the right side of an initializer expression
                    if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) {
                        return DefaultControlSpaceItems ();
                    }

                    if (initalizerResult != null && initalizerResult.Item1.Type.Kind != TypeKind.Unknown) {

                        foreach (var property in initalizerResult.Item1.Type.GetProperties ()) {
                            if (!property.IsPublic)
                                continue;
                            contextList.AddMember (property);
                        }
                        foreach (var field in initalizerResult.Item1.Type.GetFields ()) {
                            if (!field.IsPublic)
                                continue;
                            contextList.AddMember (field);
                        }
                        return contextList.Result;
                    }
                    Console.WriteLine ("blub");
                    return DefaultControlSpaceItems ();
                }
                if (n != null/* && !(identifierStart.Item2 is TypeDeclaration)*/) {
                    csResolver = new CSharpResolver (ctx);
                    var nodes = new List<AstNode> ();
                    nodes.Add (n);
                    if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute)
                        nodes.Add (n.Parent);
                    var navigator = new NodeListResolveVisitorNavigator (nodes);
                    var visitor = new ResolveVisitor (csResolver, identifierStart.Item1, navigator);
                    visitor.Scan (identifierStart.Item3);
                    try {
                        csResolver = visitor.GetResolverStateBefore (n);
                    } catch (Exception) {
                        csResolver = GetState ();
                    }
                    // add attribute properties.
                    if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
                        var resolved = visitor.GetResolveResult (n.Parent);
                        if (resolved != null && resolved.Type != null) {
                            foreach (var property in resolved.Type.GetProperties (p => p.Accessibility == Accessibility.Public)) {
                                contextList.AddMember (property);
                            }
                            foreach (var field in resolved.Type.GetFields (p => p.Accessibility == Accessibility.Public)) {
                                contextList.AddMember (field);
                            }
                        }
                    }
                } else {
                    csResolver = GetState ();
                }

                // identifier has already started with the first letter
                offset--;

                AddContextCompletion (contextList, csResolver, identifierStart.Item2);
                return contextList.Result;
            //				if (stub.Parent is BlockStatement)

            //				result = FindExpression (dom, completionContext, -1);
            //				if (result == null)
            //					return null;
            //				 else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) {
            //					triggerWordLength = 1;
            //					bool autoSelect = true;
            //					IType returnType = null;
            //					if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) {
            //						ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
            //						NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
            //						if (dataProvider != null) {
            //							int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1;
            //							foreach (var method in dataProvider.Methods) {
            //								if (i < method.Parameters.Count) {
            //									returnType = dom.GetType (method.Parameters [i].ReturnType);
            //									autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate;
            //									break;
            //								}
            //							}
            //						}
            //					}
            //					// Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature
            //					//if (result.ExpressionContext == ExpressionContext.TypeName)
            //					//	autoSelect = false;
            //					CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result);
            //					AddEnumMembers (dataList, returnType);
            //					dataList.AutoSelect = autoSelect;
            //					return dataList;
            //				} else {
            //					result = FindExpression (dom, completionContext, 0);
            //					tokenIndex = offset;
            //
            //					// check foreach case, unfortunately the expression finder is too dumb to handle full type names
            //					// should be overworked if the expression finder is replaced with a mcs ast based analyzer.
            //					var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter
            //					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname
            //
            //					// read return types to '(' token
            //					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType
            //					if (possibleForeachToken == ">") {
            //						while (possibleForeachToken != null && possibleForeachToken != "(") {
            //							possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
            //						}
            //					} else {
            //						possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // (
            //						if (possibleForeachToken == ".")
            //							while (possibleForeachToken != null && possibleForeachToken != "(")
            //								possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
            //					}
            //					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach
            //
            //					if (possibleForeachToken == "foreach") {
            //						result.ExpressionContext = ExpressionContext.ForeachInToken;
            //					} else {
            //						return null;
            //						//								result.ExpressionContext = ExpressionContext.IdentifierExpected;
            //					}
            //					result.Expression = "";
            //					result.Region = DomRegion.Empty;
            //
            //					return CreateCtrlSpaceCompletionData (completionContext, result);
            //				}
            //				break;
            }
            return null;
        }
예제 #23
0
파일: CSDemo.cs 프로젝트: jiguixin/ILSpy
		void FindReferencesButtonClick(object sender, EventArgs e)
		{
			if (csharpTreeView.SelectedNode == null)
				return;
			
			SimpleProjectContent project = new SimpleProjectContent();
			var parsedFile = new TypeSystemConvertVisitor(project, "dummy.cs").Convert(compilationUnit);
			project.UpdateProjectContent(null, parsedFile);
			
			List<ITypeResolveContext> projects = new List<ITypeResolveContext>();
			projects.Add(project);
			projects.AddRange(builtInLibs.Value);
			
			using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
				CSharpResolver resolver = new CSharpResolver(context);
				
				AstNode node = (AstNode)csharpTreeView.SelectedNode.Tag;
				IResolveVisitorNavigator navigator = new NodeListResolveVisitorNavigator(new[] { node });
				ResolveVisitor visitor = new ResolveVisitor(resolver, parsedFile, navigator);
				visitor.Scan(compilationUnit);
				IEntity entity;
				MemberResolveResult mrr = visitor.GetResolveResult(node) as MemberResolveResult;
				TypeResolveResult trr = visitor.GetResolveResult(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) {
					referenceCount++;
				};
				
				var searchScopes = fr.GetSearchScopes(entity);
				navigator = new CompositeResolveVisitorNavigator(searchScopes.Select(s => s.GetNavigator(callback)).ToArray());
				visitor = new ResolveVisitor(resolver, parsedFile, navigator);
				visitor.Scan(compilationUnit);
				
				csharpTreeView.BeginUpdate();
				ShowResolveResultsInTree(csharpTreeView.Nodes, visitor);
				csharpTreeView.EndUpdate();
				
				MessageBox.Show("Found " + referenceCount + " references to " + entity.FullName);
			}
		}
예제 #24
0
        public ResolveResult ResolveIdentifier(ResolveVisitor visitor, string identifier)
        {
            ResolveResult result = null;
             			if (resultTable.TryGetValue (identifier, out result))
             				return result;
             			resultTable[identifier] = result;

            foreach (KeyValuePair<string, List<LocalLookupVariable>> pair in this.lookupTableVisitor.Variables) {
             				if (identifier == pair.Key) {
             					LocalLookupVariable var = null;
            // 					Console.WriteLine ("--- RP:" + this.resolvePosition + "/" + pair.Value.Count);
                    foreach (LocalLookupVariable v2 in pair.Value) {
                        DomLocation varStartPos = new DomLocation (lookupVariableLine + v2.StartPos.Line, v2.StartPos.Column - 1);
                        DomLocation varEndPos   = new DomLocation (lookupVariableLine + v2.EndPos.Line, v2.EndPos.Column - 1);
            //						Console.WriteLine (v2.Name + ":" + varStartPos + " <> " + varEndPos);
                        if (varStartPos > this.resolvePosition || (!v2.EndPos.IsEmpty && varEndPos < this.resolvePosition))
                            continue;
                        var = v2;
                    }
            //					Console.WriteLine ("var:" + var);
                    if (var == null)
                        continue;
                    IReturnType varType = null;
                    IReturnType varTypeUnresolved = null;
                    if (var.IsQueryContinuation) {
                        QueryExpression query = var.Initializer as QueryExpression;

                        QueryExpressionGroupClause grouBy = query.SelectOrGroupClause as QueryExpressionGroupClause;
                        DomLocation old = resolvePosition;
                        try {
                            resolvePosition = new DomLocation (lookupVariableLine + grouBy.Projection.StartLocation.Line,
                                                               grouBy.Projection.StartLocation.Column);
                            ResolveResult initializerResolve = visitor.Resolve (grouBy.Projection);
                            ResolveResult groupByResolve = visitor.Resolve (grouBy.GroupBy);
                            DomReturnType resolved = new DomReturnType (dom.GetType ("System.Linq.IGrouping", new IReturnType [] {
                                DomType.GetComponentType (dom, initializerResolve.ResolvedType), groupByResolve.ResolvedType}));
                        varTypeUnresolved = varType = resolved;
                        } finally {
                            resolvePosition = old;
                        }

                    } else if ((var.TypeRef == null || var.TypeRef.Type == "var" || var.TypeRef.IsNull)) {
                        if (var.ParentLambdaExpression != null) {
                            ResolveResult lambdaResolve = ResolveLambda (visitor, var.ParentLambdaExpression);
                            if (lambdaResolve != null) {
                                varType           = lambdaResolve.ResolvedType;
                                varTypeUnresolved = lambdaResolve.UnresolvedType;
                            } else {
                                varType = varTypeUnresolved = DomReturnType.Void;
                            }
                        }
                        if (var.Initializer != null) {
                            ResolveResult initializerResolve = visitor.Resolve (var.Initializer);
            //							Console.WriteLine ("initializer : "+ var.Initializer + " result:" + initializerResolve);
                            varType           = var.IsLoopVariable ? DomType.GetComponentType (dom, initializerResolve.ResolvedType) : initializerResolve.ResolvedType;
                            varTypeUnresolved = var.IsLoopVariable ? DomType.GetComponentType (dom, initializerResolve.UnresolvedType) : initializerResolve.UnresolvedType;
            //							Console.WriteLine ("resolved type:" + initializerResolve.ResolvedType + " is loop : " + var.IsLoopVariable);
            //							Console.WriteLine (varType);
            //							Console.WriteLine ("----------");
                        }
                    } else {
                        varTypeUnresolved = varType = ConvertTypeReference (var.TypeRef);
                    }
            //					Console.WriteLine ("-----");
            //					Console.WriteLine (varType);
                    varType = ResolveType (varType);
                    result = new LocalVariableResolveResult (
                        new LocalVariable (CallingMember, identifier, varType,
                            new DomRegion (lookupVariableLine + var.StartPos.Line - 1, var.StartPos.Column - 1,
                                           lookupVariableLine + var.StartPos.Line - 1, var.EndPos.Column - 1)),
                            var.IsLoopVariable);

                    result.ResolvedType = varType;
                    result.UnresolvedType = varTypeUnresolved;
                    goto end;
                }
            }
            if (this.callingMember != null) {
                // special handling of property or field return types, they can have the same name as the return type
                // ex.: MyType MyType { get; set; }  Type1 Type1;
                if ((callingMember is IProperty || callingMember is IField) && identifier == callingMember.Name) {
                    int pos = editor.GetPositionFromLineColumn (resolvePosition.Line, resolvePosition.Column);
                    while (pos < editor.TextLength && !Char.IsWhiteSpace (editor.GetCharAt (pos)))
                        pos++;
                    while (pos < editor.TextLength && Char.IsWhiteSpace (editor.GetCharAt (pos)))
                        pos++;
                    StringBuilder memberName = new StringBuilder ();
                    while (pos < editor.TextLength && (Char.IsLetterOrDigit (editor.GetCharAt (pos)) || editor.GetCharAt (pos) == '_') ) {
                        memberName.Append (editor.GetCharAt (pos));
                        pos++;
                    }
                    //Console.WriteLine ("id: '" + identifier + "' : '" + memberName.ToString () +"'" + (memberName.ToString () == identifier));
                    if (memberName.ToString () == identifier) {
                        result = visitor.CreateResult (callingMember.ReturnType);
                        goto end;
                    }
                }

                if (identifier == "value" && this.callingMember is IProperty) {
                    result = new MemberResolveResult (this.callingMember);
                    result.UnresolvedType = ((IProperty)this.callingMember).ReturnType;
                    result.ResolvedType = ResolveType (((IProperty)this.callingMember).ReturnType);
                    goto end;
                }
                if (this.callingMember is IMethod || this.callingMember is IProperty) {
                    ReadOnlyCollection<IParameter> prms = this.callingMember is IMethod
                        ? ((IMethod)this.callingMember).Parameters
                        : ((IProperty)this.callingMember).Parameters;
                    if (prms != null) {
                        foreach (IParameter para in prms) {
                            if (para.Name == identifier) {
                                result = new ParameterResolveResult (para);
                                result.UnresolvedType = para.ReturnType;
                                result.ResolvedType = ResolveType (para.ReturnType);
                                goto end;
                            }
                        }
                    }
                }
            }
            IType searchedType = dom.SearchType (new SearchTypeRequest (unit, this.CallingType, identifier));
            if (this.callingType != null && dom != null) {
                List<IMember> members = new List <IMember> ();
                foreach (IType type in dom.GetInheritanceTree (callingType)) {
                    members.AddRange (type.SearchMember (identifier, true));
                }
                bool includeProtected = true;
                // filter members
                if (this.CallingMember != null) {
                    for (int i = 0; i < members.Count; i++) {
                        if (this.CallingMember.IsStatic && !members[i].IsStatic
                            || !members[i].IsAccessibleFrom (dom, callingType, this.CallingMember, includeProtected))
                        {
                            members.RemoveAt (i);
                            i--;
                            continue;
                        }
                    }
                }

                if (members.Count > 0) {
                    if (members[0] is IMethod) {
                        result = new MethodResolveResult (members);
                        if (CallingMember != null)
                            result.StaticResolve = CallingMember.IsStatic;
                    } else if (members[0] is IType) {
                        result = new MemberResolveResult (null, true);
                        result.UnresolvedType = result.ResolvedType = new DomReturnType ((IType)members[0]);
                        goto end;
                    } else {
                        result = new MemberResolveResult (members[0]);
                    }
                    result.UnresolvedType = members[0].ReturnType;
                    result.ResolvedType = ResolveType (members[0].ReturnType);
                    if (members[0] is IProperty && searchedType != null && result.ResolvedType.FullName == searchedType.FullName) {
                        result = new AggregatedResolveResult (result, new MemberResolveResult (null, true) {
                            UnresolvedType = new DomReturnType (searchedType),
                            ResolvedType = new DomReturnType (searchedType)
                        });
                    }
                    goto end;
                }
            }

            if (searchedType != null) {
                result = new MemberResolveResult (null, true);
                result.UnresolvedType = result.ResolvedType = new DomReturnType (searchedType);
                goto end;
            }

            if (dom.NamespaceExists (identifier, true)) {
                result = new NamespaceResolveResult (identifier);
                goto end;
            }

            if (unit != null && unit.Usings != null) {
                foreach (IUsing u in unit.Usings) {
                    if (u.IsFromNamespace && u.Region.Contains (resolvePosition)) {
                        foreach (string ns in u.Namespaces) {
                            if (dom.NamespaceExists (ns + "."  + identifier, true)) {
                                result = new NamespaceResolveResult (ns + "."  + identifier);
                                goto end;
                            }
                        }
                    }
                    foreach (KeyValuePair<string, IReturnType> alias in u.Aliases) {
                        if (alias.Key == identifier || alias.Key + ".?" == identifier) {
                            result = new NamespaceResolveResult (alias.Value.FullName);
                            goto end;
                        }
                    }
                }
            }

            end:
            if (result != null) {
                result.CallingType   = CallingType;
                result.CallingMember = CallingMember;
            }
            resultTable[identifier] = result;
            return result;
        }
        /// <summary>
        /// Creates a new BVE5 AST resolver.
        /// Use this overload if you are resolving code snippets (not necessarily complete files).
        /// </summary>
        /// <param name="resolver">The resolver state at the root node (to be more precise: just outside the root node).</param>
        /// <param name="rootNode">The root node of the tree to be resolved.</param>
        /// <param name="unresolvedFile">
        /// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
        /// <para>
        /// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
        /// </para>
        /// <para>
        /// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
        /// member declarations in the AST with members in the type system.
        /// When no unresolvedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
        /// member's signature in the AST with the signature in the type system.
        /// </para>
        /// </param>
        public BVE5AstResolver(BVE5Resolver resolver, AstNode rootNode, BVE5UnresolvedFile unresolvedFile = null)
        {
            if(resolver == null)
                throw new ArgumentNullException("resolver");

            if(rootNode == null)
                throw new ArgumentNullException("rootNode");

            initial_resolver_state = resolver;
            root_node = rootNode;
            unresolved_file = unresolvedFile;
            resolve_visitor = new ResolveVisitor(initial_resolver_state, unresolvedFile);
        }
예제 #26
0
 public ResolveResult ResolveLambda(ResolveVisitor visitor, Expression lambdaExpression)
 {
     return new LambdaResolver (this).ResolveLambda (visitor, lambdaExpression);
 }
예제 #27
0
		void ResolveButtonClick(object sender, EventArgs e)
		{
			SimpleProjectContent project = new SimpleProjectContent();
			TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(project, "dummy.cs");
			compilationUnit.AcceptVisitor(convertVisitor, null);
			project.UpdateProjectContent(null, convertVisitor.ParsedFile.TopLevelTypeDefinitions, null, null);
			
			List<ITypeResolveContext> projects = new List<ITypeResolveContext>();
			projects.Add(project);
			projects.AddRange(builtInLibs.Value);
			
			using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
				CSharpResolver resolver = new CSharpResolver(context);
				
				IResolveVisitorNavigator navigator = null;
				if (csharpTreeView.SelectedNode != null) {
					navigator = new NodeListResolveVisitorNavigator(new[] { (AstNode)csharpTreeView.SelectedNode.Tag });
				}
				ResolveVisitor visitor = new ResolveVisitor(resolver, convertVisitor.ParsedFile, navigator);
				visitor.Scan(compilationUnit);
				csharpTreeView.BeginUpdate();
				ShowResolveResultsInTree(csharpTreeView.Nodes, visitor);
				csharpTreeView.EndUpdate();
			}
		}
예제 #28
0
		/// <summary>
		/// Applies a resolver navigator. This will resolve the nodes requested by the navigator, and will inform the
		/// navigator of the results.
		/// This method must be called as the first operation on the CSharpAstResolver, it is invalid to apply a navigator
		/// after a portion of the file was already resolved.
		/// </summary>
		public void ApplyNavigator(IResolveVisitorNavigator navigator, CancellationToken cancellationToken = default(CancellationToken))
		{
			if (navigator == null)
				throw new ArgumentNullException("navigator");
			if (resolveVisitor != null)
				throw new InvalidOperationException("Applying a navigator is only valid as the first operation on the CSharpAstResolver.");
			resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile, navigator);
			lock (resolveVisitor)
				resolveVisitor.Scan(rootNode);
		}
예제 #29
0
		void InitResolver(AstNode firstNodeToResolve)
		{
			if (resolveVisitor == null) {
				resolveVisitor = new ResolveVisitor(initialResolverState, parsedFile, new NodeListResolveVisitorNavigator(firstNodeToResolve));
				resolveVisitor.Scan(rootNode);
			}
		}
예제 #30
0
            internal ResolveResult ResolveLambda(ResolveVisitor visitor, Expression lambdaExpression)
            {
                if (expressions.Contains (lambdaExpression)) {
                    Console.WriteLine ("LOOP!!!");
                    return null;
                }
                expressions.Add (lambdaExpression);

                if (lambdaExpression.Parent is LambdaExpression)
                    return ResolveLambda (visitor, lambdaExpression.Parent as Expression);
                if (lambdaExpression.Parent is ParenthesizedExpression)
                    return ResolveLambda (visitor, lambdaExpression.Parent as Expression);
                if (lambdaExpression.Parent is AssignmentExpression)
                    return visitor.Resolve (((AssignmentExpression)lambdaExpression.Parent).Left);
                if (lambdaExpression.Parent is CastExpression)
                    return visitor.Resolve (((CastExpression)lambdaExpression.Parent));
                if (lambdaExpression.Parent is VariableDeclaration) {
                    VariableDeclaration varDec = (VariableDeclaration)lambdaExpression.Parent;
                    return resolver.GetFunctionParameterType (resolver.ResolveIdentifier (visitor, varDec.Name));
                }
                if (lambdaExpression.Parent is InvocationExpression) {
                    InvocationExpression invocation = (InvocationExpression)lambdaExpression.Parent;
                    MethodResolveResult result = visitor.Resolve (invocation.TargetObject) as MethodResolveResult;
                    if (result == null) {
                        MonoDevelop.Core.LoggingService.LogWarning ("No compatible method found :" + invocation.TargetObject);
                        return null;
                    }
                    result.ResolveExtensionMethods ();

                    // todo! - not 100% correct, but it's a best-fit until the dom contains token information
                    // This code assumes that the lambda expression is the first parameter of the method.
                    for (int i = 0; i < invocation.Arguments.Count; i++) {
                        if (invocation.Arguments[i] == lambdaExpression && i < result.MostLikelyMethod.Parameters.Count) {
                            IParameter parameter = result.MostLikelyMethod.Parameters[i];
                            IReturnType returnType = parameter.ReturnType;

                            while (returnType.GenericArguments.Count > 0) {
                                returnType = returnType.GenericArguments[0];
                            }
                            string invariantString = returnType.ToInvariantString ();
                            if (returnTypeDictionary.ContainsKey (invariantString))
                                return returnTypeDictionary[invariantString];
                            ResolveResult createdResult = visitor.CreateResult (returnType);
                            returnTypeDictionary[invariantString] = createdResult;
                            return createdResult;
                        }
                    }

                    LambdaExpression lambda = (LambdaExpression)lambdaExpression;
                //				Console.WriteLine ("lambda:" + lambda);
                    if (!lambda.ExpressionBody.IsNull) {
                        DomLocation old = resolver.resolvePosition;
                        try {
                            resolver.resolvePosition = new DomLocation (resolver.CallingMember.Location.Line + resolver.lookupVariableLine +
                                                               lambda.ExpressionBody.StartLocation.Line - 2,
                                                               lambda.ExpressionBody.StartLocation.Column - 1);
                //						Console.WriteLine ("pos:" + resolvePosition);
                //						result.AddArgument (visitor.GetTypeSafe (lambda.ExpressionBody));
                //						result.ResolveExtensionMethods ();
                            ResolveResult res =  visitor.Resolve (lambda.ExpressionBody);
                //						Console.WriteLine (lambda.ExpressionBody);
                //						Console.WriteLine ("RES:" + res.ResolvedType.FullName);
                            if (!string.IsNullOrEmpty (res.ResolvedType.FullName))
                                return res;
                        } finally {
                            resolver.resolvePosition = old;
                        }
                    }

                    foreach (Expression arg in invocation.Arguments) {
                        var argType = arg is LambdaExpression ?  DomReturnType.Void : visitor.GetTypeSafe (arg);
                        result.AddArgument (argType);
                    }

                    result.ResolveExtensionMethods ();
                    //Console.WriteLine ("maybe method:" + result.MostLikelyMethod);
                    for (int i = 0; i < invocation.Arguments.Count; i++) {
                        if (invocation.Arguments [i] == lambdaExpression && i < result.MostLikelyMethod.Parameters.Count) {
                            IParameter parameterType = result.MostLikelyMethod.Parameters [i];
                            //Console.WriteLine (i + " par: " + parameterType);
                            if (parameterType.ReturnType.Name == "Func" && parameterType.ReturnType.GenericArguments.Count > 0) {
                                return visitor.CreateResult (parameterType.ReturnType.GenericArguments[0]);
                            }
                        }
                    }
                    return result;
                }

                if (lambdaExpression.Parent is ObjectCreateExpression) {
                    ObjectCreateExpression objectCreateExpression = (ObjectCreateExpression)lambdaExpression.Parent;
                    int index = objectCreateExpression.Parameters.IndexOf (lambdaExpression);
                    if (index < 0)
                        return null;
                    MemberResolveResult resolvedCreateExpression = visitor.Resolve (objectCreateExpression) as MemberResolveResult;

                    if (resolvedCreateExpression != null) {
                        IMethod method = resolvedCreateExpression.ResolvedMember as IMethod;
                        if (method!= null && index < method.Parameters.Count) {
                            return new ParameterResolveResult (method.Parameters[index]);
                        } else {
                            return null;
                        }
                    }
                }

                return null;
            }
예제 #31
0
		void ShowResolveResultsInTree(TreeNodeCollection c, ResolveVisitor v)
		{
			foreach (TreeNode t in c) {
				AstNode node = t.Tag as AstNode;
				if (node != null) {
					ResolveResult rr = v.GetResolveResult(node);
					if (rr != null)
						t.Text = GetNodeTitle(node) + " " + rr.ToString();
					else
						t.Text = GetNodeTitle(node);
				}
				ShowResolveResultsInTree(t.Nodes, v);
			}
		}
예제 #32
0
		/// <summary>
		/// Finds all references in the given file.
		/// </summary>
		/// <param name="searchScopes">The search scopes for which to look.</param>
		/// <param name="parsedFile">The type system representation of the file being searched.</param>
		/// <param name="compilationUnit">The compilation unit of the file being searched.</param>
		/// <param name="context">The type resolve context to use for resolving the file.</param>
		/// <param name="callback">Callback used to report the references that were found.</param>
		public void FindReferencesInFile(IList<IFindReferenceSearchScope> searchScopes, CSharpParsedFile parsedFile, CompilationUnit compilationUnit,
		                                 ITypeResolveContext context, FoundReferenceCallback callback)
		{
			if (searchScopes == null)
				throw new ArgumentNullException("searchScopes");
			if (parsedFile == null)
				throw new ArgumentNullException("parsedFile");
			if (compilationUnit == null)
				throw new ArgumentNullException("compilationUnit");
			if (context == null)
				throw new ArgumentNullException("context");
			this.CancellationToken.ThrowIfCancellationRequested();
			if (searchScopes.Count == 0)
				return;
			using (var ctx = context.Synchronize()) {
				IResolveVisitorNavigator navigator;
				if (searchScopes.Count == 1)
					navigator = searchScopes[0].GetNavigator(callback);
				else
					navigator = new CompositeResolveVisitorNavigator(searchScopes.Select(s => s.GetNavigator(callback)).ToArray());
				navigator = new DetectSkippableNodesNavigator(navigator, compilationUnit);
				CSharpResolver resolver = new CSharpResolver(ctx, this.CancellationToken);
				ResolveVisitor v = new ResolveVisitor(resolver, parsedFile, navigator);
				v.Scan(compilationUnit);
			}
		}
예제 #33
0
 public ResolveResult ResolveExpression(Expression expr, DomLocation resolvePosition)
 {
     this.expr = expr;
     this.SetupResolver (resolvePosition);
     ResolveVisitor visitor = new ResolveVisitor (this);
     ResolveResult result = visitor.Resolve (expr);
     return result;
 }
예제 #34
0
 public ResolveResult ResolveIdentifier(string identifier, DomLocation resolvePosition)
 {
     this.SetupResolver (resolvePosition);
     ResolveVisitor visitor = new ResolveVisitor (this);
     ResolveResult result = this.ResolveIdentifier (visitor, identifier);
     return result;
 }
예제 #35
0
		/// <summary>
		/// Creates a new C# AST resolver.
		/// Use this overload if you are resolving code snippets (not necessarily complete files).
		/// </summary>
		/// <param name="resolver">The resolver state at the root node (to be more precise: just outside the root node).</param>
		/// <param name="rootNode">The root node of the tree to be resolved.</param>
		/// <param name="unresolvedFile">
		/// Optional: Result of <see cref="SyntaxTree.ToTypeSystem()"/> for the file being resolved.
		/// <para>
		/// This is used for setting up the context on the resolver. The unresolved file must be registered in the compilation.
		/// </para>
		/// <para>
		/// When a unresolvedFile is specified, the resolver will use the member's StartLocation/EndLocation to identify
		/// member declarations in the AST with members in the type system.
		/// When no unresolvedFile is specified (<c>null</c> value for this parameter), the resolver will instead compare the
		/// member's signature in the AST with the signature in the type system.
		/// </para>
		/// </param>
		public CSharpAstResolver(CSharpResolver resolver, AstNode rootNode, CSharpUnresolvedFile unresolvedFile = null)
		{
			if (resolver == null)
				throw new ArgumentNullException("resolver");
			if (rootNode == null)
				throw new ArgumentNullException("rootNode");
			this.initialResolverState = resolver;
			this.rootNode = rootNode;
			this.unresolvedFile = unresolvedFile;
			this.resolveVisitor = new ResolveVisitor(initialResolverState, unresolvedFile);
		}
예제 #36
0
        public ResolveResult Resolve(ExpressionResult expressionResult, DomLocation resolvePosition)
        {
            this.SetupResolver (resolvePosition);
            ResolveVisitor visitor = new ResolveVisitor (this);
            ResolveResult result;
            //			System.Console.WriteLine("expressionResult:" + expressionResult);

            if (unit != null && expressionResult.ExpressionContext == ExpressionContext.AttributeArguments) {
                string attributeName = NewFSharpExpressionFinder.FindAttributeName (editor, unit, unit.FileName);
                if (attributeName != null) {
                    IType type = dom.SearchType (new SearchTypeRequest (unit, new DomReturnType (attributeName + "Attribute"), CallingType));
                    if (type == null)
                        type = dom.SearchType (new SearchTypeRequest (unit, new DomReturnType (attributeName), CallingType));
                    if (type != null) {
                        foreach (IProperty property in type.Properties) {
                            if (property.Name == expressionResult.Expression) {
                                return new MemberResolveResult (property);
                            }
                        }
                    }
                }
            }

            TypeReference typeRef;
            if (expressionResult != null && expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.IsObjectCreation) {
                typeRef = ParseTypeReference (expressionResult);
                if (typeRef != null) {
                    if (dom.NamespaceExists (typeRef.Type)) {
            //						System.Console.WriteLine("namespace resolve result");
                        result = new NamespaceResolveResult (typeRef.Type);
                    } else {
                        result = visitor.CreateResult (ConvertTypeReference (typeRef));
                    }
            //					System.Console.WriteLine("type reference resolve result");
                    result.ResolvedExpression = expressionResult;
                    if (dom.GetType (result.ResolvedType) != null)
                        return result;
                }
            }
            expr = ParseExpression (expressionResult);

            //			System.Console.WriteLine("parsed expression:" + expr);
            if (expr == null) {
            //				System.Console.WriteLine("Can't parse expression");
                return null;
            }

            result = visitor.Resolve (expr);
            //			if (CallingMember == null && result != null)
            //				result.StaticResolve = true;
            //			System.Console.WriteLine("result:" + result + "STATIC" + result.StaticResolve);
            result.ResolvedExpression = expressionResult;
            return result;
        }