/// <summary>
        /// Registers a binder factory. The supplied name prefixed with "data-" is used
        /// as the attribute name in markup to create a binder.
        /// </summary>
        /// <param name="name">The name of the expression handler.</param>
        /// <param name="factory">The factory being registered.</param>
        public void RegisterBinder(string name, BinderFactory factory)
        {
            Debug.Assert(String.IsNullOrEmpty(name) == false);
            Debug.Assert(factory != null);
            Debug.Assert(_registeredBinders.ContainsKey(name) == false, "A binder with name '" + name + "' was already registered.");

            _registeredBinders[name] = factory;
        }
        internal SyntaxTreeSemanticModel(CSharpCompilation compilation, SyntaxTree syntaxTree)
        {
            _compilation = compilation;
            _syntaxTree = syntaxTree;
            if (!this.Compilation.SyntaxTrees.Contains(syntaxTree))
            {
                throw new ArgumentOutOfRangeException("tree", CSharpResources.TreeNotPartOfCompilation);
            }

            _binderFactory = compilation.GetBinderFactory(SyntaxTree);
        }
        internal SyntaxTreeSemanticModel(CSharpCompilation compilation, SyntaxTree syntaxTree, bool ignoreAccessibility = false)
        {
            _compilation = compilation;
            _syntaxTree = syntaxTree;
            _ignoresAccessibility = ignoreAccessibility;

            if (!this.Compilation.SyntaxTrees.Contains(syntaxTree))
            {
                throw new ArgumentOutOfRangeException(nameof(syntaxTree), CSharpResources.TreeNotPartOfCompilation);
            }

            _binderFactory = compilation.GetBinderFactory(SyntaxTree);
        }
        internal SyntaxTreeSemanticModel(LanguageCompilation compilation, LanguageSyntaxTree syntaxTree, bool ignoreAccessibility = false)
        {
            _compilation          = compilation;
            _ignoresAccessibility = ignoreAccessibility;

            if (!this.Compilation.SyntaxTrees.Contains(syntaxTree))
            {
                throw new ArgumentOutOfRangeException(nameof(syntaxTree), CSharpResources.TreeNotPartOfCompilation);
            }

            _boundTree = new BoundTree(compilation, syntaxTree, compilation.GetBinder(syntaxTree.GetRootNode()), _ignoredDiagnostics);

            _binderFactory = compilation.GetBinderFactory(SyntaxTree);
        }
        public static Expression <Func <Scope, object> > Generate(Block block, BinderFactory factory, string fileName)
        {
            Contract.Requires <ArgumentNullException>(block != null);
            Contract.Requires <ArgumentNullException>(factory != null);
            Contract.Requires <ArgumentNullException>(fileName != null);

            var        global = Expression.Parameter(typeof(Scope), "global");
            var        gen    = new GlobalGen(fileName, factory, global);
            Expression expr   = gen.Generate(block);

            if (expr.Type != typeof(object))
            {
                expr = Expression.Convert(expr, typeof(object));
            }
            return(Expression.Lambda <Func <Scope, object> >(expr, "プログラム", new[] { global }));
        }
Exemple #6
0
        private void AddDelegateMembers(
            ArrayBuilder <Symbol> symbols,
            DelegateDeclarationSyntax syntax,
            BinderFactory binderFactory,
            DiagnosticBag diagnostics)
        {
            var bodyBinder = binderFactory.GetBinder(syntax.ParameterList);

            // A delegate has the following members: (see CLI spec 13.6)
            // (1) a method named Invoke with the specified signature
            var invoke = new DelegateInvokeMethodImplementation(this, syntax, bodyBinder, diagnostics);

            invoke.CheckMethodVarianceSafety(diagnostics);
            symbols.Add(invoke);

            // (2) a constructor with argument types (object, System.IntPtr)
            symbols.Add(new DelegateConstructor(this, syntax, bodyBinder));

            var delegateBinder = new DelegateBinder(bodyBinder, this, invoke);

            // (3) BeginInvoke
            symbols.Add(new DelegateBeginInvokeMethod(this, syntax, delegateBinder, diagnostics));

            // and (4) EndInvoke methods
            symbols.Add(new DelegateEndInvokeMethod(this, syntax, delegateBinder, diagnostics));

            if (this.DeclaredAccessibility <= Accessibility.Private)
            {
                return;
            }

            if (!this.IsNoMoreVisibleThan(invoke.ReturnType))
            {
                // Inconsistent accessibility: return type '{1}' is less accessible than delegate '{0}'
                diagnostics.Add(ErrorCode.ERR_BadVisDelegateReturn, Locations[0], this, invoke.ReturnType);
            }

            foreach (var parameter in invoke.Parameters)
            {
                if (!parameter.Type.IsAtLeastAsVisibleAs(this))
                {
                    // Inconsistent accessibility: parameter type '{1}' is less accessible than delegate '{0}'
                    diagnostics.Add(ErrorCode.ERR_BadVisDelegateParam, Locations[0], this, parameter.Type);
                }
            }
        }
        private void AddDelegateMembers(
            ArrayBuilder<Symbol> symbols,
            DelegateDeclarationSyntax syntax,
            BinderFactory binderFactory,
            DiagnosticBag diagnostics)
        {
            var bodyBinder = binderFactory.GetBinder(syntax.ParameterList);

            // A delegate has the following members: (see CLI spec 13.6)
            // (1) a method named Invoke with the specified signature
            var invoke = new DelegateInvokeMethodImplementation(this, syntax, bodyBinder, diagnostics);
            invoke.CheckMethodVarianceSafety(diagnostics);
            symbols.Add(invoke);

            // (2) a constructor with argument types (object, System.IntPtr)
            symbols.Add(new DelegateConstructor(this, syntax, bodyBinder));

            var delegateBinder = new DelegateBinder(bodyBinder, this, invoke);

            // (3) BeginInvoke
            symbols.Add(new DelegateBeginInvokeMethod(this, syntax, delegateBinder, diagnostics));

            // and (4) EndInvoke methods
            symbols.Add(new DelegateEndInvokeMethod(this, syntax, delegateBinder, diagnostics));

            if (this.DeclaredAccessibility <= Accessibility.Private)
            {
                return;
            }

            if (!this.IsNoMoreVisibleThan(invoke.ReturnType))
            {
                // Inconsistent accessibility: return type '{1}' is less accessible than delegate '{0}'
                diagnostics.Add(ErrorCode.ERR_BadVisDelegateReturn, Locations[0], this, invoke.ReturnType);
            }

            foreach (var parameter in invoke.Parameters)
            {
                if (!parameter.Type.IsAtLeastAsVisibleAs(this))
                {
                    // Inconsistent accessibility: parameter type '{1}' is less accessible than delegate '{0}'
                    diagnostics.Add(ErrorCode.ERR_BadVisDelegateParam, Locations[0], this, parameter.Type);
                }
            }

        }
 internal SyntaxTreeSemanticModel(CSharpCompilation parentCompilation, SyntaxTree parentSyntaxTree, SyntaxTree speculatedSyntaxTree)
 {
     _compilation = parentCompilation;
     _syntaxTree = speculatedSyntaxTree;
     _binderFactory = _compilation.GetBinderFactory(parentSyntaxTree);
 }
 public abstract BinderFactoryVisitor CreateBinderFactoryVisitor(BinderFactory binderFactory);
Exemple #10
0
        public void CrefTypeParameterEquality1()
        {
            var source = @"
/// <see cref=""C{Q}""/>
class C<T>
{
}
";

            var compilation = CreateCompilationWithMscorlibAndDocumentationComments(source);
            compilation.VerifyDiagnostics();

            var tree = compilation.SyntaxTrees.Single();
            var cref = GetCrefSyntaxes(compilation).Single();

            Func<Symbol> lookupSymbol = () =>
            {
                var factory = new BinderFactory(compilation, tree);
                var binder = factory.GetBinder(cref);
                var lookupResult = LookupResult.GetInstance();
                HashSet<DiagnosticInfo> useSiteDiagnostics = null;
                binder.LookupSymbolsSimpleName(
                    lookupResult,
                    qualifierOpt: null,
                    plainName: "Q",
                    arity: 0,
                    basesBeingResolved: null,
                    options: LookupOptions.Default,
                    diagnose: false,
                    useSiteDiagnostics: ref useSiteDiagnostics);
                Assert.Equal(LookupResultKind.Viable, lookupResult.Kind);
                var symbol = lookupResult.Symbols.Single();
                lookupResult.Free();
                Assert.NotNull(symbol);
                Assert.IsType<CrefTypeParameterSymbol>(symbol);
                return symbol;
            };

            var symbol1 = lookupSymbol();
            var symbol2 = lookupSymbol();
            Assert.Equal(symbol1, symbol2); // Required for correctness.
            Assert.NotSame(symbol1, symbol2); // Not required, just documenting.
        }
Exemple #11
0
        private void SetupBindings(Element element, object model)
        {
            Debug.Assert(element != null);

            string bindings = (string)element.GetAttribute(Application.BindingsAttribute);

            bindings.ReplaceRegex(Application.BindingsRegex, delegate(string match /*, string binderType, string expressionType, string expressionValue */) {
                string binderType      = (string)Arguments.GetArgument(1);
                string expressionType  = (string)Arguments.GetArgument(2);
                string expressionValue = (string)Arguments.GetArgument(3);

                ExpressionFactory expressionFactory = _registeredExpressions[expressionType];
                Debug.Assert(expressionFactory != null, "Unknown expression of type '" + expressionType + "' found.");

                if (expressionFactory != null)
                {
                    Expression expression = expressionFactory(model, expressionType, expressionValue);
                    Binder binder         = null;

                    // TODO: Add support for binding attributes - @xxx

                    if (binderType.StartsWith("on."))
                    {
                        Debug.Assert(expression.CanChange == false, "Events cannot be bound to dynamic expressions.");
                        Debug.Assert(expression.GetValue() is Action);

                        binder = new EventBinder(element, binderType.Substr(3), (ElementEventListener)expression.GetValue());
                    }
                    else if (binderType.StartsWith("style."))
                    {
                        object style = element.Style;
                        binder       = new PropertyBinder(style, binderType.Substr(6), expression);
                    }
                    else
                    {
                        BinderFactory binderFactory = _registeredBinders[binderType];
                        if (binderFactory == null)
                        {
                            binder = new PropertyBinder(element, binderType, expression);
                        }
                        else
                        {
                            binder = binderFactory(element, binderType, expression);
                        }
                    }

                    if (binder != null)
                    {
                        binder.Update();
                        if (expression.CanChange == false)
                        {
                            // Since the expression value cannot change, there isn't a whole lot of need
                            // to keep the binder alive and manage it.
                            binder = null;
                        }
                    }

                    if (binder != null)
                    {
                        // The binder is managed using a behavior that is attached to the element.
                        // This allows stashing the model for later retrieval, as well as a way to
                        // dispose bindings (the behavior disposes all binders it is managing).

                        BinderManager binderManager = (BinderManager)Behavior.GetBehavior(element, typeof(BinderManager));
                        if (binderManager == null)
                        {
                            binderManager = new BinderManager();
                            binderManager.Initialize(element, null);
                            binderManager.Model = model;
                        }

                        binderManager.AddBinder(binder);
                    }
                }

                return(String.Empty);
            });
        }
 public override BinderFactoryVisitor CreateBinderFactoryVisitor(BinderFactory binderFactory)
 {
     return(new SoalBinderFactoryVisitor(binderFactory));
 }
 internal SyntaxTreeSemanticModel(LanguageCompilation parentCompilation, LanguageSyntaxTree parentSyntaxTree, LanguageSyntaxTree speculatedSyntaxTree)
 {
     _compilation   = parentCompilation;
     _boundTree     = new BoundTree(parentCompilation, speculatedSyntaxTree, parentCompilation.GetBinder(speculatedSyntaxTree.GetRootNode()), _ignoredDiagnostics);
     _binderFactory = _compilation.GetBinderFactory(parentSyntaxTree);
 }
        internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics)
        {
            var concept    = ImplementingMethod.ContainingType;
            var conceptLoc = concept.Locations.IsEmpty ? Location.None : concept.Locations[0];

            // TODO: wrong location?

            Debug.Assert(concept.IsConcept, "Tried to synthesise default struct implementation on a non-concept interface");

            var instance    = ContainingType;
            var instanceLoc = instance.Locations.IsEmpty ? Location.None : instance.Locations[0];

            // TODO: wrong location?

            Debug.Assert(instance.IsInstance, "Tried to synthesise default struct implementation for a non-instance");

            SyntheticBoundNodeFactory F = new SyntheticBoundNodeFactory(this, this.GetNonNullSyntaxNode(), compilationState, diagnostics);

            F.CurrentMethod = OriginalDefinition;

            try
            {
                // Now try to find the default struct using the instance's scope...
                var binder = new BinderFactory(compilationState.Compilation, instance.GetNonNullSyntaxNode().SyntaxTree).GetBinder(instance.GetNonNullSyntaxNode());

                var ignore = new HashSet <DiagnosticInfo>();
                var defs   = concept.GetDefaultStruct(binder, false, ref ignore);

                if (defs == null)
                {
                    diagnostics.Add(ErrorCode.ERR_ConceptMethodNotImplementedAndNoDefault, instanceLoc, instance.Name, concept.Name, ImplementingMethod.ToDisplayString());
                    F.CloseMethod(F.ThrowNull());
                    return;
                }

                // Suppose the target concept is Foo<A, B>.
                // Then, the default must take type parameters <A, B, FooAB>,
                // where FooAB : Foo<A, B>.  Thus, the arity is one higher than
                // the concept.
                if (defs.Arity != concept.Arity + 1)
                {
                    // Don't use the default struct's location: it is an
                    // implementation detail and may not actually exist.
                    diagnostics.Add(ErrorCode.ERR_DefaultStructBadArity, conceptLoc, concept.Name, defs.Arity, concept.Arity + 1);
                    F.CloseMethod(F.ThrowNull());
                    return;
                }

                // Due to above, arity must be at least 1.

                var witnessPar = defs.TypeParameters[defs.Arity - 1];
                if (!witnessPar.IsConceptWitness)
                {
                    diagnostics.Add(ErrorCode.ERR_DefaultStructNoWitnessParam, conceptLoc, concept.Name);
                    F.CloseMethod(F.ThrowNull());
                    return;
                }

                var newTypeArguments = GenerateDefaultTypeArguments();
                Debug.Assert(newTypeArguments.Length == concept.TypeArguments.Length + 1,
                             "Conversion from concept type parameters to default struct lost or gained some entries.");

                // Now make the receiver for the call.  As usual, it's a default().
                var recvType = new ConstructedNamedTypeSymbol(defs, newTypeArguments);
                var receiver = F.Default(recvType);

                var arguments = GenerateInnerCallArguments(F);
                Debug.Assert(arguments.Length == ImplementingMethod.Parameters.Length,
                             "Conversion from parameters to arguments lost or gained some entries.");

                var call = F.MakeInvocationExpression(BinderFlags.None, F.Syntax, receiver, ImplementingMethod.Name, arguments, diagnostics, ImplementingMethod.TypeArguments);
                if (call.HasErrors)
                {
                    F.CloseMethod(F.ThrowNull());
                    return;
                }

                // If whichever call we end up making returns void, then we
                // can't just return its result; instead, we have to do the
                // call on its own _then_ return.
                BoundBlock block;
                if (call.Type.SpecialType == SpecialType.System_Void)
                {
                    block = F.Block(F.ExpressionStatement(call), F.Return());
                }
                else
                {
                    block = F.Block(F.Return(call));
                }

                F.CloseMethod(block);
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                F.CloseMethod(F.ThrowNull());
            }
        }
Exemple #15
0
 public ProduireInvokeMemberBinder(string name, CallInfo callInfo, BinderFactory factory, ReferenceCollection reference)
     : base(name, callInfo, factory)
 {
     _reference = reference;
 }
Exemple #16
0
 public BinderFactoryVisitor(BinderFactory factory, ISymbol?containingSymbol)
 {
     this.factory          = factory;
     this.containingSymbol = containingSymbol;
 }
        private BinderFactory AddNewFactory(SyntaxTree syntaxTree, ref WeakReference<BinderFactory> slot)
        {
            var newFactory = new BinderFactory(this, syntaxTree);
            var newWeakReference = new WeakReference<BinderFactory>(newFactory);

            while (true)
            {
                BinderFactory previousFactory;
                WeakReference<BinderFactory> previousWeakReference = slot;
                if (previousWeakReference != null && previousWeakReference.TryGetTarget(out previousFactory))
                {
                    return previousFactory;
                }

                if (Interlocked.CompareExchange(ref slot, newWeakReference, previousWeakReference) == previousWeakReference)
                {
                    return newFactory;
                }
            }
        }
Exemple #18
0
        static int Main(string[] args)
        {
            const string usageMessage = "Usage:\nepoxy <configuration json file>";

            if (args.Length != 1 || args[0] == "-h" || args[0] == "--help")
            {
                Console.Error.WriteLine(usageMessage);
                return(-1);
            }

            string configurationJsonFilePath = args[0];

            if (!File.Exists(configurationJsonFilePath))
            {
                Console.Error.WriteLine($"Configuration file '{configurationJsonFilePath}' does not exist.");

                if (!Path.IsPathRooted(configurationJsonFilePath))
                {
                    Console.Error.WriteLine($"Path appears to be relative and the current working directory is '{Directory.GetCurrentDirectory()}'.");
                }

                return(-2);
            }

            Configuration config = JsonConvert.DeserializeObject <Configuration>(File.ReadAllText(configurationJsonFilePath));

            (bool configIsValid, string message) = config.Validate();
            if (!configIsValid)
            {
                if (!message.IsNullOrEmpty())
                {
                    Console.Error.WriteLine($"Invalid configuration: {message}");
                }

                return(-3);
            }

            Graph graph = GraphLoader.LoadGraph(Directory.EnumerateFiles(config.DoxygenXmlDirectory).Where(file => Path.GetExtension(file) == ".xml"));

            if (graph == null)
            {
                Console.Error.WriteLine("Failed to load C++ library definitions successfully.");
                return(-4);
            }

            foreach (BinderConfiguration binderConfig in config.Binders)
            {
                IBinder binder = BinderFactory.GetBinder(binderConfig);
                if (binder == null)
                {
                    Console.WriteLine($"Warning: language '{binderConfig.Language}' currently does not have a binder implemented-skipping.");
                    continue;
                }

                binder.GenerateNativeBindings(graph);
                binder.GenerateLanguageBindings(graph);
            }

            Console.WriteLine("SUCCESS");
            return(0);
        }