示例#1
0
        public override ResolveResult Resolve(CppResolver resolver)
        {
            ResolveResult lhs = left.Resolve(resolver);
            ResolveResult rhs = right.Resolve(resolver);

            return(resolver.ResolveBinaryOperator(operatorType, lhs, rhs));
        }
示例#2
0
            public override object Invoke(CppResolver resolver, object lhs, object rhs)
            {
                if (lhs == null && rhs == null)
                {
                    return(!Negate);                    // ==: true; !=: false
                }
                if (lhs == null || rhs == null)
                {
                    return(Negate);                    // ==: false; !=: true
                }
                lhs = resolver.CSharpPrimitiveCast(Type, lhs);
                rhs = resolver.CSharpPrimitiveCast(Type, rhs);
                bool equal;

                if (Type == TypeCode.Single)
                {
                    equal = (float)lhs == (float)rhs;
                }
                else if (Type == TypeCode.Double)
                {
                    equal = (double)lhs == (double)rhs;
                }
                else
                {
                    equal = object.Equals(lhs, rhs);
                }
                return(equal ^ Negate);
            }
		public IList<ResolveResult> GetArgumentsWithConversions()
		{
			if (bestCandidate == null)
				return arguments;
			var conversions = this.ArgumentConversions;
			ResolveResult[] args = new ResolveResult[arguments.Length];
			for (int i = 0; i < args.Length; i++) {
				if (conversions[i] == Conversion.IdentityConversion) {
					args[i] = arguments[i];
				} else {
					int parameterIndex = bestCandidate.ArgumentToParameterMap[i];
					IType parameterType;
					if (parameterIndex >= 0) {
						parameterType = bestCandidate.ParameterTypes[parameterIndex];
					} else {
						parameterType = SpecialType.UnknownType;
					}
					if (arguments[i].IsCompileTimeConstant && conversions[i] != Conversion.None) {
						args[i] = new CppResolver(compilation).ResolveCast(parameterType, arguments[i]);
					} else {
						args[i] = new ConversionResolveResult(parameterType, arguments[i], conversions[i]);
					}
				}
			}
			return args;
		}
示例#4
0
        public IEnumerable <IEnumerable <IMethod> > GetEligibleExtensionMethods(bool substituteInferredTypes)
        {
            var result = new List <List <IMethod> >();

            foreach (var methodGroup in GetExtensionMethods())
            {
                var outputGroup = new List <IMethod>();
                foreach (var method in methodGroup)
                {
                    IType[] inferredTypes;
                    if (CppResolver.IsEligibleExtensionMethod(
                            method.Compilation, Conversions.Get(method.Compilation),
                            this.TargetType, method, true, out inferredTypes))
                    {
                        if (substituteInferredTypes && inferredTypes != null)
                        {
                            outputGroup.Add(new SpecializedMethod(method.DeclaringType, method, inferredTypes));
                        }
                        else
                        {
                            outputGroup.Add(method);
                        }
                    }
                }
                if (outputGroup.Count > 0)
                {
                    result.Add(outputGroup);
                }
            }
            return(result);
        }
示例#5
0
            InvocationResolveResult GetCtorInvocation()
            {
                ResolveResult rr = this.ctorInvocation;

                if (rr != null)
                {
                    LazyInit.ReadBarrier();
                    return(rr as InvocationResolveResult);
                }
                else
                {
                    CppResolver     resolver           = new CppResolver(context);
                    int             totalArgumentCount = unresolved.positionalArguments.Count + unresolved.namedCtorArguments.Count;
                    ResolveResult[] arguments          = new ResolveResult[totalArgumentCount];
                    string[]        argumentNames      = new string[totalArgumentCount];
                    int             i = 0;
                    while (i < unresolved.positionalArguments.Count)
                    {
                        IConstantValue cv = unresolved.positionalArguments[i];
                        arguments[i] = cv.Resolve(context);
                        i++;
                    }
                    foreach (var pair in unresolved.namedCtorArguments)
                    {
                        argumentNames[i] = pair.Key;
                        arguments[i]     = pair.Value.Resolve(context);
                        i++;
                    }
                    rr = resolver.ResolveObjectCreation(attributeType, arguments, argumentNames);
                    return(LazyInit.GetOrSet(ref this.ctorInvocation, rr) as InvocationResolveResult);
                }
            }
示例#6
0
 public override ResolveResult Resolve(CppResolver resolver)
 {
     return(resolver.ResolveConditional(
                condition.Resolve(resolver),
                trueExpr.Resolve(resolver),
                falseExpr.Resolve(resolver)
                ));
 }
示例#7
0
 public override object Invoke(CppResolver resolver, object input)
 {
     if (input == null)
     {
         return(null);
     }
     return(func((T)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T)), input)));
 }
示例#8
0
 /// <summary>
 /// Creates a new TypeSystemAstBuilder.
 /// </summary>
 /// <param name="resolver">
 /// A resolver initialized for the position where the type will be inserted.
 /// </param>
 public TypeSystemAstBuilder(CppResolver resolver)
 {
     if (resolver == null)
     {
         throw new ArgumentNullException("resolver");
     }
     this.resolver = resolver;
     InitProperties();
 }
示例#9
0
 public override object Invoke(CppResolver resolver, object lhs, object rhs)
 {
     if (lhs == null || rhs == null)
     {
         return(null);
     }
     return(func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs),
                 (T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs)));
 }
示例#10
0
        public IList <ControlFlowNode> BuildControlFlowGraph(Statement statement, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (statement == null)
            {
                throw new ArgumentNullException("statement");
            }
            CppResolver r = new CppResolver(MinimalCorlib.Instance.CreateCompilation());

            return(BuildControlFlowGraph(statement, new CppAstResolver(r, statement), cancellationToken));
        }
示例#11
0
        bool AreEqualConstants(ResolveResult c1, ResolveResult c2)
        {
            if (c1 == null || c2 == null || !c1.IsCompileTimeConstant || !c2.IsCompileTimeConstant)
            {
                return(false);
            }
            CppResolver   r = new CppResolver(typeResolveContext);
            ResolveResult c = r.ResolveBinaryOperator(BinaryOperatorType.Equality, c1, c2);

            return(c.IsCompileTimeConstant && (c.ConstantValue as bool?) == true);
        }
示例#12
0
            public override object Invoke(CppResolver resolver, object lhs, object rhs)
            {
                if (lhs == null || rhs == null)
                {
                    return(null);
                }
                Func <T1, T2, T1> func = resolver.CheckForOverflow ? checkedFunc : uncheckedFunc;

                return(func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs),
                            (T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs)));
            }
示例#13
0
 /// <summary>
 /// Gets all candidate extension methods.
 /// Note: this includes candidates that are not eligible due to an inapplicable
 /// this argument.
 /// </summary>
 /// <remarks>
 /// The results are stored in nested lists because they are grouped by using scope.
 /// That is, for "using SomeExtensions; namespace X { using MoreExtensions; ... }",
 /// the return value will be
 /// new List {
 ///    new List { all extensions from MoreExtensions },
 ///    new List { all extensions from SomeExtensions }
 /// }
 /// </remarks>
 public IEnumerable <IEnumerable <IMethod> > GetExtensionMethods()
 {
     if (resolver != null)
     {
         Debug.Assert(extensionMethods == null);
         try {
             extensionMethods = resolver.GetExtensionMethods(methodName, typeArguments);
         } finally {
             resolver = null;
         }
     }
     return(extensionMethods ?? Enumerable.Empty <IEnumerable <IMethod> >());
 }
示例#14
0
        public override ResolveResult Resolve(CppResolver resolver)
        {
            ResolveResult rr;

            if (targetType != null)
            {
                rr = new TypeResolveResult(targetType.Resolve(resolver.CurrentTypeResolveContext));
            }
            else
            {
                rr = targetExpression.Resolve(resolver);
            }
            return(resolver.ResolveMemberAccess(rr, memberName, typeArguments.Resolve(resolver.CurrentTypeResolveContext)));
        }
示例#15
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);
 }
示例#16
0
 public override ResolveResult Resolve(CppResolver resolver)
 {
     ResolveResult[] elements = new ResolveResult[arrayElements.Count];
     for (int i = 0; i < elements.Length; i++)
     {
         elements[i] = arrayElements[i].Resolve(resolver);
     }
     if (elementType != null)
     {
         return(resolver.ResolveArrayCreation(elementType.Resolve(resolver.CurrentTypeResolveContext), 1, null, elements));
     }
     else
     {
         return(resolver.ResolveArrayCreation(null, 1, null, elements));
     }
 }
示例#17
0
 /// <summary>
 /// Gets the resolver state immediately before the specified node.
 /// That is, if the node is a variable declaration, the returned state will not contain the newly declared variable.
 /// </summary>
 public CppResolver GetResolverStateBefore(AstNode node, CancellationToken cancellationToken = default(CancellationToken))
 {
     if (node == null || node.IsNull)
     {
         throw new ArgumentNullException("node");
     }
     InitResolver();
     resolveVisitor.cancellationToken = cancellationToken;
     try {
         CppResolver resolver = resolveVisitor.GetResolverStateBefore(node);
         Debug.Assert(resolver != null);
         return(resolver);
     } finally {
         resolveVisitor.cancellationToken = CancellationToken.None;
     }
 }
示例#18
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);
 }
        public override ResolveResult Resolve(CppResolver resolver)
        {
            ResolveResult targetRR = target.Resolve(resolver);

            if (targetRR.IsError)
            {
                return(targetRR);
            }
            IList <IType> typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext);

            using (var busyLock = BusyManager.Enter(this)) {
                if (busyLock.Success)
                {
                    return(resolver.ResolveMemberType(targetRR, identifier, typeArgs));
                }
                else
                {
                    // This can happen for "class Test : $Test.Base$ { public class Base {} }":
                    return(ErrorResolveResult.UnknownError);                    // don't cache this error
                }
            }
        }
        List <string> GetUsedNamespaces()
        {
            var scope    = CSharpParsedFile.GetUsingScope(location);
            var result   = new List <string> ();
            var resolver = new CppResolver(ctx);

            while (scope != null)
            {
                result.Add(scope.NamespaceName);

                foreach (var u in scope.Usings)
                {
                    var ns = u.ResolveNamespace(resolver);
                    if (ns == null)
                    {
                        continue;
                    }
                    result.Add(ns.FullName);
                }
                scope = scope.Parent;
            }
            return(result);
        }
示例#21
0
 /// <summary>
 /// Gets the resolver state immediately after the specified node.
 /// That is, if the node is a variable declaration, the returned state will include the newly declared variable.
 /// </summary>
 public CppResolver GetResolverStateAfter(AstNode node, CancellationToken cancellationToken = default(CancellationToken))
 {
     if (node == null || node.IsNull)
     {
         throw new ArgumentNullException("node");
     }
     while (node != null && IsUnresolvableNode(node))
     {
         node = node.Parent;
     }
     if (node == null)
     {
         return(initialResolverState);
     }
     InitResolver();
     resolveVisitor.cancellationToken = cancellationToken;
     try {
         CppResolver resolver = resolveVisitor.GetResolverStateAfter(node);
         Debug.Assert(resolver != null);
         return(resolver);
     } finally {
         resolveVisitor.cancellationToken = CancellationToken.None;
     }
 }
示例#22
0
 public override ResolveResult Resolve(CppResolver resolver)
 {
     return(resolver.ResolveCast(targetType.Resolve(resolver.CurrentTypeResolveContext), expression.Resolve(resolver)));
 }
示例#23
0
 public override ResolveResult Resolve(CppResolver resolver)
 {
     return(resolver.ResolveUnaryOperator(operatorType, expression.Resolve(resolver)));
 }
示例#24
0
 public override ResolveResult Resolve(CppResolver resolver)
 {
     return(resolver.ResolveDefaultValue(type.Resolve(resolver.CurrentTypeResolveContext)));
 }
示例#25
0
 public override ResolveResult Resolve(CppResolver resolver)
 {
     return(expression.Resolve(resolver.WithCheckForOverflow(checkForOverflow)));
 }
示例#26
0
        public override ResolveResult Resolve(CppResolver resolver)
        {
            var typeArgs = typeArguments.Resolve(resolver.CurrentTypeResolveContext);

            return(resolver.LookupSimpleNameOrTypeName(identifier, typeArgs, lookupMode));
        }
示例#27
0
 public override ResolveResult Resolve(CppResolver resolver)
 {
     return(resolver.ResolveSimpleName(identifier, typeArguments.Resolve(resolver.CurrentTypeResolveContext)));
 }
示例#28
0
 public abstract ResolveResult Resolve(CppResolver resolver);
示例#29
0
 public override ResolveResult Resolve(CppResolver resolver)
 {
     return(resolver.ResolveTypeOf(type.Resolve(resolver.CurrentTypeResolveContext)));
 }
示例#30
0
 public override ResolveResult Resolve(CppResolver resolver)
 {
     return(new ConstantResolveResult(type.Resolve(resolver.CurrentTypeResolveContext), value));
 }