Beispiel #1
0
        public Compiler(Log log, Backend backend, SourcePackage package, CompilerOptions options)
            : base(log)
        {
            // This is a block of dependency injection to initialize the Compiler
            var il         = new Namespace();
            var extensions = new ExtensionRoot();

            Backend = backend;
            var disk = Disk = new Disk(log, true);

            Shell = new Shell(log);
            var essentials   = Essentials = new Essentials();
            var resolver     = NameResolver = new NameResolver(this);
            var ilf          = ILFactory = new ILFactory(backend, il, essentials, resolver, this);
            var data         = Data = new BuildData(il, extensions, ilf);
            var environment  = Environment = new BuildEnvironment(backend, package, options, extensions, ilf, this);
            var input        = Input = new SourceReader(log, package, environment);
            var blockBuilder = BlockBuilder = new BlockBuilder(backend, il, ilf, resolver, this);
            var typeBuilder  = TypeBuilder = new TypeBuilder(environment, ilf, resolver, this);
            var bundle       = BundleBuilder = new BundleBuilder(backend, environment, ilf, this);

            AstProcessor = new AstProcessor(il, blockBuilder, typeBuilder, resolver, environment);
            UxlProcessor = new UxlProcessor(disk, backend.Name, il, extensions, environment, ilf);
            Plugins      = new PluginCache(log, bundle, ilf, environment);
            var pass = Pass = new CompilerPass(disk, data, environment, ilf, backend, input.Package, typeBuilder, resolver);

            Utilities      = new Utilities(il, pass);
            ILVerifier     = new ILVerifier(pass);
            ConstantFolder = new ConstantFolder(pass);
            ILStripper     = new ILStripper(pass);
        }
Beispiel #2
0
 FunctionCompiler(Compiler compiler)
     : base(compiler)
 {
     Environment  = compiler.Environment;
     Essentials   = compiler.Essentials;
     ILFactory    = compiler.ILFactory;
     ILVerifier   = compiler.ILVerifier;
     TypeBuilder  = compiler.TypeBuilder;
     NameResolver = compiler.NameResolver;
     Compiler     = compiler;
 }
        public PartialExpression TryResolveTypeMember(DataType dt, AstIdentifier id, int?typeParamCount, AstExpression qualifier, Expression instance)
        {
            var result = NameResolver.TryGetTypeMemberCached(dt, id.Symbol, typeParamCount);

            if (result == null ||
                dt.Methods.Count == 1 && dt.Methods[0].GenericType == dt)
            {
                return(null);
            }

            if (dt.IsFlattenedDefinition)
            {
                return(PartialError(id.Source, ErrorCode.I0000, "Invalid member-access on non-parameterized type"));
            }

            var methods = result as IReadOnlyList <Method>;

            if (methods != null)
            {
                return(new PartialMethodGroup(id.Source, instance, !AllowStaticContext(qualifier, instance), methods));
            }

            var literal = result as Literal;

            if (literal != null)
            {
                if (AllowStaticContext(qualifier, instance))
                {
                    ILVerifier.VerifyConstUsage(id.Source, literal, Function);
                    return(new PartialValue(new Constant(id.Source, literal.ReturnType, literal.Value is AstExpression
                            ? Compiler.CompileConstant((AstExpression)literal.Value, literal.DeclaringType, literal.ReturnType).Value
                            : literal.Value)));
                }

                return(PartialError(id.Source, ErrorCode.E0000, literal.Quote() + " is a constant -- qualify with the type name"));
            }

            var field = result as Field;

            if (field != null)
            {
                if (field.IsStatic)
                {
                    if (instance != null)
                    {
                        return(AllowStaticContext(qualifier, instance)
                            ? new PartialField(id.Source, field, null)
                            : PartialError(id.Source, ErrorCode.E3117, field.Quote() + " is static -- qualify with the type name"));
                    }
                }
                else
                {
                    if (instance == null)
                    {
                        return(qualifier == null && TryResolveDataTypeIdentifier(id) == field.ReturnType
                            ? new PartialType(id.Source, field.ReturnType)
                            : PartialError(id.Source, ErrorCode.E3118, field.Quote() + " is non-static and cannot be accessed from a static context"));
                    }
                }

                return(new PartialField(id.Source, field, instance));
            }

            var ev = result as Event;

            if (ev != null)
            {
                if (ev.IsStatic)
                {
                    if (instance != null)
                    {
                        return(AllowStaticContext(qualifier, instance)
                            ? new PartialEvent(id.Source, ev, null)
                            : PartialError(id.Source, ErrorCode.E3119, ev.Quote() + " is static -- qualify with the type name"));
                    }
                }
                else
                {
                    if (instance == null)
                    {
                        return(qualifier == null && TryResolveDataTypeIdentifier(id) == ev.ReturnType
                            ? new PartialType(id.Source, ev.ReturnType)
                            : PartialError(id.Source, ErrorCode.E3120, ev.Quote() + " is non-static and cannot be accessed from a static context"));
                    }
                }

                return(new PartialEvent(id.Source, ev, instance));
            }

            var prop = result as Property;

            if (prop != null)
            {
                if (prop.IsStatic)
                {
                    if (instance != null)
                    {
                        return(AllowStaticContext(qualifier, instance)
                            ? new PartialProperty(id.Source, prop, null)
                            : PartialError(id.Source, ErrorCode.E3121, prop.Quote() + " is static -- qualify with the type name"));
                    }
                }
                else
                {
                    if (instance == null)
                    {
                        return(qualifier == null && TryResolveDataTypeIdentifier(id) == prop.ReturnType
                            ? new PartialType(id.Source, prop.ReturnType)
                            : PartialError(id.Source, ErrorCode.E3122, prop.Quote() + " is non-static and cannot be accessed from a static context"));
                    }
                }

                return(new PartialProperty(id.Source, prop, instance));
            }

            var genericParam = result as GenericParameterType;

            if (genericParam != null)
            {
                return(qualifier == null ?
                       new PartialType(id.Source, genericParam) :
                       null);
            }

            var innerType  = result as DataType;
            var innerBlock = result as Block;

            if (innerType != null || innerBlock != null)
            {
                return(AllowStaticContext(qualifier, instance)
                    ? (innerType != null
                        ? (PartialExpression) new PartialType(id.Source, innerType)
                        :                     new PartialBlock(id.Source, innerBlock))
                    : PartialError(id.Source, ErrorCode.E0000, "Cannot reference block or type " + result.Quote() + " through an expression -- qualify with the type name"));
            }

            return(result is List <object>
                   ?PartialError(id.Source, ErrorCode.E0000, (dt + "." + id.GetParameterizedSymbol(typeParamCount)).Quote() + " is ambiguous. This can be resolved using an explicit cast to a more specific interface type")
                       : result as PartialExpression ??
                       PartialError(id.Source, ErrorCode.I0000, "Unknown type member: " + result));
        }
Beispiel #4
0
        public Expression CompileImport(AstImport import)
        {
            if (import.Arguments == null)
            {
                var c = Compiler.CompileConstant(import.Importer, Namescope, Essentials.String);
                if (c.IsInvalid)
                {
                    return(c);
                }

                var filename = c.ConstantString;
                Compiler.Disk.GetFullPath(import.Importer.Source, ref filename);
                return(Compiler.BundleBuilder.AddBundleFile(import.Importer.Source, filename));
            }

            // TODO: Remove deprecated legacy code below
            var importer = Compiler.TryCompileSuffixedObject(Namescope, import.Importer, "Importer", import.Arguments);

            if (importer == null)
            {
                return(Expression.Invalid);
            }

            if (importer.ReturnType.Base == null ||
                importer.ReturnType.Base.MasterDefinition != Essentials.Importer_T)
            {
                return(Error(importer.Source, ErrorCode.E0000, "Importer must be a type derived directly from " + Essentials.Importer_T.Quote()));
            }

            ILVerifier.VerifyConstUsage(import.Source, importer.Constructor, Function);

            Importer plugin;

            if (!Compiler.Plugins.TryGetImporter(importer.ReturnType.MasterDefinition, out plugin))
            {
                return(Error(import.Importer.Source, ErrorCode.E2048, "Unsupported importer " + importer.ReturnType.Quote()));
            }

            PathFlags flags          = 0;
            var       isMetaProperty = MetaProperty != null;

            if (isMetaProperty)
            {
                flags |= PathFlags.WarnIfNonExistingPath;
            }
            if (import.Source.IsUnknown || Path.GetExtension(import.Source.FullPath).ToUpperInvariant() != ".UNO")
            {
                flags |= PathFlags.AllowAbsolutePath;
            }

            if (!Compiler.ExpandFilenames(importer, flags))
            {
                if (isMetaProperty)
                {
                    for (int i = 0; i < importer.Arguments.Length; i++)
                    {
                        if (importer.Constructor.Parameters[i].HasAttribute(Essentials.FilenameAttribute))
                        {
                            var c = importer.Arguments[i] as Constant;

                            if (c != null)
                            {
                                var src      = c.Source;
                                var filename = c.Value as string;
                                AddReqStatement(new ReqFile(src, filename));
                            }
                        }
                    }
                }

                return(Expression.Invalid);
            }

            var types = importer.ReturnType.IsGenericParameterization ?
                        importer.ReturnType.GenericArguments :
                        null;

            return(CompileImplicitCast(
                       import.Source,
                       importer.ReturnType.Base.GenericArguments[0],
                       plugin.Import(
                           new ImportContext(
                               import.Source,
                               types,
                               importer.GetArgumentValues()))));
        }