예제 #1
0
파일: Name.cs 프로젝트: zlaski/ql
        public static Expression Create(ExpressionNodeInfo info)
        {
            var symbolInfo = info.Context.GetSymbolInfo(info.Node);

            var target = symbolInfo.Symbol;

            if (target == null && symbolInfo.CandidateReason == CandidateReason.OverloadResolutionFailure)
            {
                // The expression is probably a cast
                target = info.Context.GetSymbolInfo((CSharpSyntaxNode)info.Node.Parent).Symbol;
            }

            if (target == null && (symbolInfo.CandidateReason == CandidateReason.Ambiguous || symbolInfo.CandidateReason == CandidateReason.MemberGroup))
            {
                // Pick one at random - they probably resolve to the same ID
                target = symbolInfo.CandidateSymbols.First();
            }

            if (target == null)
            {
                info.Context.ModelError(info.Node, "Failed to resolve name");
                return(new Unknown(info));
            }

            // There is a very strange bug in Microsoft.CodeAnalysis whereby
            // target.Kind throws System.InvalidOperationException for Discard symbols.
            // So, short-circuit that test here.
            // Ideally this would be another case in the switch statement below.
            if (target is IDiscardSymbol)
            {
                return(new Discard(info));
            }

            switch (target.Kind)
            {
            case SymbolKind.TypeParameter:
            case SymbolKind.NamedType:
            case SymbolKind.DynamicType:
                return(TypeAccess.Create(info));

            case SymbolKind.Property:
            case SymbolKind.Field:
            case SymbolKind.Event:
            case SymbolKind.Method:
                return(Access.Create(info, target, true, info.Context.CreateEntity(target)));

            case SymbolKind.Local:
            case SymbolKind.RangeVariable:
                return(Access.Create(info, target, false, LocalVariable.GetAlreadyCreated(info.Context, target)));

            case SymbolKind.Parameter:
                return(Access.Create(info, target, false, Parameter.GetAlreadyCreated(info.Context, (IParameterSymbol)target)));

            case SymbolKind.Namespace:
                return(Access.Create(info, target, false, Namespace.Create(info.Context, (INamespaceSymbol)target)));

            default:
                throw new InternalError(info.Node, $"Unhandled identifier kind '{target.Kind}'");
            }
        }
예제 #2
0
            protected Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement, ISymbol variableSymbol, SyntaxToken name)
            {
                var type = Type.Create(cx, cx.GetType(Expr));

                Extraction.Entities.Location nameLoc;

                Type       declType;
                TypeSyntax declTypeSyntax = null;

                if (getElement)
                {
                    var from = node as FromClauseSyntax;
                    (declType, declTypeSyntax) = from != null && from.Type != null
                         ? (Type.Create(cx, cx.GetType(from.Type)), from.Type)
                         : (type.ElementType, null);
                }
                else
                {
                    declType = type;
                }

                var decl = VariableDeclaration.Create(cx,
                                                      variableSymbol,
                                                      declType,
                                                      declTypeSyntax,
                                                      cx.Create(node.GetLocation()),
                                                      nameLoc = cx.Create(name.GetLocation()),
                                                      true,
                                                      parent,
                                                      child
                                                      );

                Expression.Create(cx, Expr, decl, 0);

                var access = new Expression(new ExpressionInfo(cx, type, nameLoc, ExprKind.LOCAL_VARIABLE_ACCESS, decl, 1, false, null));

                cx.Emit(Tuples.expr_access(access, LocalVariable.GetAlreadyCreated(cx, variableSymbol)));

                return(decl);
            }