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); }
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)); }
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())))); }