private string  LoadSourceCode(string sourceCodeFile)
        {
            sourceCodeFile = Path.GetFullPath(sourceCodeFile);

            if (!File.Exists(sourceCodeFile))
            {
                throw new FileNotFoundException(sourceCodeFile);
            }

            if (_fileNameList.Contains(sourceCodeFile))
            {
                _logger.LogIt(LogSeverity.Warn, "i18n::Warning: recursion detected, {0} already loaded", sourceCodeFile);
                return(string.Empty);
            }


            _fileNameList.Add(sourceCodeFile);

            var sb = new StringBuilder();

            var listOfAdditionalFiles = new List <string>();

            foreach (var sl in File.ReadLines(sourceCodeFile))
            {
                if (sl.Contains("using ", StringComparison.InvariantCulture))
                {
                    _usingList.Add(sl);
                    continue;
                }

                if (sl.Contains("//@meta::include", StringComparison.InvariantCultureIgnoreCase))
                {
                    var fileName = sl.Replace("//@meta::include", string.Empty, StringComparison.InvariantCultureIgnoreCase)
                                   .Replace("\"", string.Empty, StringComparison.CurrentCultureIgnoreCase);

                    fileName = Path.GetFileName(Path.GetFullPath(fileName));

                    listOfAdditionalFiles.Add(Path.Combine(Path.GetDirectoryName(sourceCodeFile), fileName));
                    continue;
                }

                sb.AppendLine(sl);
            }


            foreach (var fileName in listOfAdditionalFiles)
            {
                sb.AppendLine(LoadSourceCode(fileName));
            }

            return(sb.ToString());
        }
        public void Compile(ProgramArgs prgArgs, TypeInfoData typeInfoData)
        {
            _logger = typeInfoData.Logger;

            _usingList.Clear();
            _fileNameList.Clear();

            var sourceCode = LoadSourceCode(prgArgs.File);

            var u = _usingList.Distinct().Aggregate((i, j) => i + Environment.NewLine + j);

            sourceCode = u + Environment.NewLine + sourceCode;


            using (var peStream = new MemoryStream())
            {
                var result = GenerateCode(sourceCode, typeInfoData.MetadataReferenceList).Emit(peStream);

                if (!result.Success)
                {
                    var failures = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error);

                    foreach (var diagnostic in failures)
                    {
                        _logger.LogIt(LogSeverity.Error, "{0}: {1} at {2}", diagnostic.Id, diagnostic.GetMessage(), diagnostic.Location);
                    }

                    _logger.LogIt(LogSeverity.Fatal, "i18n::Compilation failed");
                    throw new Exception("Compilation failed");
                }

                _logger.LogIt(LogSeverity.Info, "i18n::Compilation done without any error.");

                peStream.Seek(0, SeekOrigin.Begin);
                typeInfoData.Assembly = Assembly.Load(peStream.ToArray());
            }
        }
Example #3
0
        public void Inspect(ILogging logger, ExtendedFieldInfo efi)
        {
            var fieldType = efi.FieldInfo.FieldType;

            efi.TypeCode = Type.GetTypeCode(fieldType);


            SetTypeCodeForPrimitives(efi);

            if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                var t = Nullable.GetUnderlyingType(fieldType);

                if (t != null)
                {
                    efi.TypeCode   = Type.GetTypeCode(t);
                    efi.IsNullable = true;

                    SetTypeCodeForPrimitives(efi);
                }
            }


            if (fieldType.IsArray)
            {
                efi.TypeCode = Type.GetTypeCode(fieldType.GetElementType());
                efi.AvroType = AvroFieldType.Array;
            }


            if (fieldType.IsClass)
            {
                efi.ImplementingClassName = fieldType.Name;
            }

            if (efi.IsClass && efi.TypeCode != TypeCode.String && !fieldType.IsArray)
            {
                efi.AvroType = AvroFieldType.Record;
            }



            if (fieldType.IsGenericType)
            {
                var underlyingName = fieldType.UnderlyingSystemType.Name;

                efi.IsMap = underlyingName.Contains("Dictionary", StringComparison.InvariantCultureIgnoreCase) ||
                            underlyingName.Contains("SortedList", StringComparison.InvariantCultureIgnoreCase) ||
                            underlyingName.Contains("SortedDictionary", StringComparison.InvariantCultureIgnoreCase);

                if (efi.IsMap)
                {
                    if (fieldType.GenericTypeArguments[0] != typeof(string))
                    {
                        logger.LogIt(LogSeverity.Fatal, "i18n::Key of AVRO::MAP must be a string, error in field " + efi.FieldName);
                        throw new NotSupportedException();
                    }

                    efi.TypeCode = Type.GetTypeCode(fieldType.GenericTypeArguments[1]);

                    efi.AvroType = AvroFieldType.Map;


                    if (efi.TypeCode == TypeCode.Object)
                    {
                        efi.AvroType = AvroFieldType.MapWithRecordType;

                        efi.ComplexArrayOrMapType = fieldType.GenericTypeArguments[1];
                        efi.ImplementingClassName = efi.ComplexArrayOrMapType.Name;
                    }
                }
            }


            if (fieldType.IsClass && fieldType.IsArray)
            {
                efi.ImplementingClassName = fieldType.Name.Replace("[]", string.Empty, StringComparison.InvariantCultureIgnoreCase);

                if (efi.TypeCode == TypeCode.Object)
                {
                    efi.AvroType = AvroFieldType.ArrayWithRecordType;

                    efi.ComplexArrayOrMapType = fieldType.GetElementType();
                }
            }


            efi.AvroDefaultValue = efi.FieldInfo.GetCustomAttribute <AvroDefaultValueAttribute>()?.DefaultValue;
            efi.HasDefaultValue  = efi.AvroDefaultValue != null;


            var fsAttr = efi.FieldInfo.GetCustomAttribute <AvroFixedAttribute>();

            if (fsAttr != null)
            {
                efi.AvroType            = AvroFieldType.Fixed;
                efi.FixedFieldSize      = fsAttr.Size;
                efi.FixedFieldClassName = fsAttr.DataClassName;

                if (efi.TypeCode != TypeCode.Byte)
                {
                    logger.LogIt(LogSeverity.Fatal, "i18n::FIXED is not allowed for other types than type BYTE, field: " + efi.FieldName);
                    throw new NotSupportedException("FIXED is not allowed for other types than type BYTE, field: " + efi.FieldName);
                }

                if (string.IsNullOrWhiteSpace(efi.FixedFieldClassName))
                {
                    logger.LogIt(LogSeverity.Fatal, "i18n::You must provide a DataClassName via attribute, field: " + efi.FieldName);
                    throw new ArgumentException("You must provide a DataClassName via attribute, field: " + efi.FieldName);
                }
            }

            var aliasAttr = efi.FieldInfo.GetCustomAttribute <AvroAliasAttribute>()?.AliasList;

            if (aliasAttr != null)
            {
                efi.AliasList.AddRange(aliasAttr);
            }


            var docValueAttr = efi.FieldInfo.GetCustomAttribute <AvroDocAttribute>()?.DocValue;

            if (!string.IsNullOrWhiteSpace(docValueAttr))
            {
                efi.AvroDocValue = docValueAttr;
                efi.HasDocValue  = true;
            }


            var nsValueAttr = efi.FieldInfo.GetCustomAttribute <AvroNamespaceAttribute>()?.NamespaceValue;

            if (!string.IsNullOrWhiteSpace(nsValueAttr))
            {
                efi.AvroNameSpace = nsValueAttr;
                efi.HasNamespace  = true;
            }

            logger.LogIt(LogSeverity.Verbose, "i18n::Field {0} determined as {1}", efi.FieldName, efi.AvroType);
        }