Esempio n. 1
0
 /// <summary>
 /// Creates an instance that can be used for method body compilation.
 /// The instance can be reused for successive <see cref="CompileBody"/> calls.
 /// </summary>
 /// <param name="declarationProvider">The provider for method and type declarations.</param>
 /// <param name="diagnosticSink">The receiver for any semantic errors or warnings.</param>
 public MethodCompiler(
     IDeclarationProvider declarationProvider,
     IDiagnosticSink diagnosticSink)
 {
     _declarationProvider = declarationProvider;
     _diagnostics         = diagnosticSink;
     _variableMap         = new ScopedVariableMap();
 }
        public void SetUp()
        {
            _adviceDeclarationProviderMock = MockRepository.GenerateStrictMock <IDeclarationProvider> ();
            _weaverMock         = MockRepository.GenerateStrictMock <IWeaver> ();
            _adviceComposerMock = MockRepository.GenerateStrictMock <IAdviceComposer>();
            _mutableType        = ObjectMother.GetMutableType();

            _assembler = new Assembler(_adviceDeclarationProviderMock, _adviceComposerMock, _weaverMock);
        }
Esempio n. 3
0
 public Participant(
     IDeclarationProvider declarationProvider,
     IAdviceComposer adviceComposer,
     IAdviceWeaver adviceWeaver,
     IIntertypeWeaver intertypeWeaver,
     IEventMethodPreparer eventMethodPreparer)
 {
     _declarationProvider = declarationProvider;
     _adviceComposer      = adviceComposer;
     _adviceWeaver        = adviceWeaver;
     _intertypeWeaver     = intertypeWeaver;
     _eventMethodPreparer = eventMethodPreparer;
 }
Esempio n. 4
0
        /// <summary>
        /// Verifies and creates type information for the method.
        /// Returns null if this fails, in which case diagnostics are also emitted.
        /// The name is not checked for duplication in this method.
        /// </summary>
        /// <param name="syntax">The syntax tree for the method.</param>
        /// <param name="definingNamespace">The name of the namespace this method is in.</param>
        /// <param name="definingFilename">The name of the file that contains the method.</param>
        /// <param name="methodBodyIndex">The index associated with the compiled method body.</param>
        /// <param name="declarationProvider">The type provider to use for resolving custom types.</param>
        /// <param name="diagnosticSink">The receiver for any semantic errors or warnings.</param>
        public static MethodDeclaration?Compile(
            FunctionSyntax syntax,
            string definingNamespace,
            string definingFilename,
            int methodBodyIndex,
            IDeclarationProvider declarationProvider,
            IDiagnosticSink diagnosticSink)
        {
            // Resolve the return type
            if (!TypeResolver.TryResolve(syntax.ReturnType, diagnosticSink, out var returnType))
            {
                return(null);
            }
            Debug.Assert(returnType != null);

            // Resolve parameter types
            // The parameter names are checked in InternalCompile()
            var parameterTypes = ImmutableList <TypeDefinition> .Empty;

            foreach (var param in syntax.Parameters)
            {
                if (!TypeResolver.TryResolve(param.Type, diagnosticSink, out var paramType))
                {
                    return(null);
                }
                Debug.Assert(paramType != null);
                if (paramType.Equals(SimpleType.Void))
                {
                    diagnosticSink.Add(DiagnosticCode.VoidIsNotValidType, param.Position, param.Name);
                    return(null);
                }
                parameterTypes = parameterTypes.Add(paramType);
            }

            // Apply the attributes
            // Each attribute can be validated independently, so don't stop on first failure
            var isEntryPoint = false;
            var isValid      = true;

            byte[]? importName    = null;
            byte[]? importLibrary = null;
            foreach (var attribute in syntax.Attributes)
            {
                switch (attribute.Name)
                {
                case "EntryPoint":
                    isValid     &= ValidateEntryPoint(syntax, diagnosticSink, returnType, parameterTypes);
                    isEntryPoint = true;
                    break;

                case "Import":
                    isValid &= TryParseImportAttribute(attribute, diagnosticSink, out importName, out importLibrary);
                    break;

                default:
                    diagnosticSink.Add(DiagnosticCode.UnknownAttribute, attribute.Position, attribute.Name);
                    isValid = false;
                    break;
                }
            }

            if (!isValid)
            {
                return(null);
            }

            // Some attributes may not be applied to the same method
            if (isEntryPoint && importName != null)
            {
                diagnosticSink.Add(DiagnosticCode.EntryPointAndImportNotCompatible, syntax.Position);
                return(null);
            }

            // Return a suitable subtype of the MethodDeclaration class
            if (importName != null)
            {
                Debug.Assert(importLibrary != null);

                return(new ImportedMethodDeclaration(methodBodyIndex, returnType, parameterTypes, syntax.Visibility,
                                                     definingNamespace + "::" + syntax.Name, definingFilename, syntax.Position, importName, importLibrary));
            }
            else
            {
                return(new NativeMethodDeclaration(methodBodyIndex, returnType, parameterTypes, syntax.Visibility,
                                                   definingNamespace + "::" + syntax.Name, definingFilename, syntax.Position, isEntryPoint));
            }
        }