示例#1
0
文件: CSEX.cs 项目: knat/SData
        internal static void MapGlobalTypes(NamespaceInfoMap nsInfoMap, INamespaceSymbol nsSymbol)
        {
            if (!nsSymbol.IsGlobalNamespace)
            {
                foreach (var nsInfo in nsInfoMap.Values)
                {
                    if (nsSymbol.FullNameEquals(nsInfo.DottedName.NameParts))
                    {
                        var typeSymbolList = nsSymbol.GetMembers().OfType<INamedTypeSymbol>().Where(i => i.TypeKind == Microsoft.CodeAnalysis.TypeKind.Class).ToList();
                        for (var i = 0; i < typeSymbolList.Count;)
                        {
                            var typeSymbol = typeSymbolList[i];
                            var clsAttData = typeSymbol.GetAttributeData(SchemaClassAttributeNameParts);
                            if (clsAttData != null)
                            {
                                if (typeSymbol.IsGenericType)
                                {
                                    CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.SchemaClassCannotBeGeneric), GetTextSpan(typeSymbol));
                                }
                                if (typeSymbol.IsStatic)
                                {
                                    CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.SchemaClassCannotBeStatic), GetTextSpan(typeSymbol));
                                }
                                var clsName = GetFirstArgumentAsString(clsAttData);
                                if (clsName == null)
                                {
                                    CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.InvalidSchemaClassAttribute), GetTextSpan(clsAttData));
                                }
                                var clsInfo = nsInfo.TryGetGlobalType<ClassTypeInfo>(clsName);
                                if (clsInfo == null)
                                {
                                    CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.InvalidSchemaClassAttributeName, clsName), GetTextSpan(clsAttData));
                                }
                                if (clsInfo.Symbol != null)
                                {
                                    CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.DuplicateSchemaClassAttributeName, clsName), GetTextSpan(clsAttData));
                                }
                                if (!clsInfo.IsAbstract)
                                {
                                    if (typeSymbol.IsAbstract)
                                    {
                                        CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.NonAbstractSchemaClassRequired),
                                            GetTextSpan(typeSymbol));
                                    }
                                    if (!typeSymbol.HasParameterlessConstructor())
                                    {
                                        CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.ParameterlessConstructorRequired),
                                            GetTextSpan(typeSymbol));
                                    }
                                }
                                clsInfo.Symbol = typeSymbol;
                                typeSymbolList.RemoveAt(i);
                                continue;
                            }
                            ++i;
                        }

                        foreach (var typeSymbol in typeSymbolList)
                        {
                            if (!typeSymbol.IsGenericType)
                            {
                                var clsName = typeSymbol.Name;
                                var clsInfo = nsInfo.TryGetGlobalType<ClassTypeInfo>(clsName);
                                if (clsInfo != null)
                                {
                                    if (clsInfo.Symbol == null)
                                    {
                                        if (typeSymbol.IsStatic)
                                        {
                                            CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.SchemaClassCannotBeStatic), GetTextSpan(typeSymbol));
                                        }
                                        if (!clsInfo.IsAbstract)
                                        {
                                            if (typeSymbol.IsAbstract)
                                            {
                                                CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.NonAbstractSchemaClassRequired),
                                                    GetTextSpan(typeSymbol));
                                            }
                                            if (!typeSymbol.HasParameterlessConstructor())
                                            {
                                                CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.ParameterlessConstructorRequired),
                                                    GetTextSpan(typeSymbol));
                                            }
                                        }
                                        clsInfo.Symbol = typeSymbol;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            foreach (var subNsSymbol in nsSymbol.GetNamespaceMembers())
            {
                MapGlobalTypes(nsInfoMap, subNsSymbol);
            }
        }
示例#2
0
文件: CSEX.cs 项目: knat/SData
 internal static int MapNamespaces(NamespaceInfoMap nsInfoMap, IAssemblySymbol assSymbol, bool isRef)
 {
     var count = 0;
     foreach (AttributeData attData in assSymbol.GetAttributes())
     {
         if (attData.AttributeClass.FullNameEquals(isRef ? __CompilerSchemaNamespaceAttributeNameParts : SchemaNamespaceAttributeNameParts))
         {
             var ctorArgs = attData.ConstructorArguments;
             string uri = null, dottedString = null;
             var ctorArgsLength = ctorArgs.Length;
             if (ctorArgsLength >= 2)
             {
                 uri = ctorArgs[0].Value as string;
                 if (uri != null)
                 {
                     dottedString = ctorArgs[1].Value as string;
                 }
             }
             if (dottedString == null)
             {
                 if (isRef)
                 {
                     CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.Invalid__CompilerSchemaNamespaceAttribute,
                         assSymbol.Identity.Name), default(TextSpan));
                 }
                 else
                 {
                     CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.InvalidSchemaNamespaceAttribute),
                         GetTextSpan(attData));
                 }
             }
             NamespaceInfo nsInfo;
             if (!nsInfoMap.TryGetValue(uri, out nsInfo))
             {
                 if (isRef)
                 {
                     continue;
                 }
                 else
                 {
                     CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.InvalidSchemaNamespaceAttributeUri, uri),
                         GetTextSpan(attData));
                 }
             }
             if (nsInfo.DottedName != null)
             {
                 if (isRef)
                 {
                     CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.Duplicate__CompilerSchemaNamespaceAttributeUri,
                         uri, assSymbol.Identity.Name), default(TextSpan));
                 }
                 else
                 {
                     CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.DuplicateSchemaNamespaceAttributeUri, uri),
                         GetTextSpan(attData));
                 }
             }
             CSDottedName dottedName;
             if (!CSDottedName.TryParse(dottedString, out dottedName))
             {
                 if (isRef)
                 {
                     CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.Invalid__CompilerSchemaNamespaceAttributeNamespaceName,
                         dottedString, assSymbol.Identity.Name), default(TextSpan));
                 }
                 else
                 {
                     CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.InvalidSchemaNamespaceAttributeNamespaceName, dottedString),
                         GetTextSpan(attData));
                 }
             }
             nsInfo.DottedName = dottedName;
             nsInfo.IsRef = isRef;
             ++count;
             if (isRef)
             {
                 if (ctorArgsLength >= 4)
                 {
                     var ca2 = ctorArgs[2];
                     var ca3 = ctorArgs[3];
                     nsInfo.SetRefData(ca2.IsNull ? null : ca2.Values.Select(i => i.Value as string),
                        ca3.IsNull ? null : ca3.Values.Select(i => i.Value as string));
                 }
                 else
                 {
                     CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.Invalid__CompilerSchemaNamespaceAttribute,
                         assSymbol.Identity.Name), default(TextSpan));
                 }
             }
         }
     }
     return count;
 }
示例#3
0
        public static bool Compile(IReadOnlyList<string> schemaFileList,
            IReadOnlyList<string> csFileList, IReadOnlyList<string> csPpList, IReadOnlyList<MetadataReference> csRefList, string csAssemblyName,
            out LoadingContext context, out string csCode)
        {
            context = null;
            csCode = _csGeneratedFileBanner;
            if (schemaFileList == null || schemaFileList.Count == 0)
            {
                return true;
            }
            try
            {
                context = CompilerContext.Current = new CompilerContext();
                var cuList = new List<CompilationUnitNode>();
                foreach (var schemaFile in schemaFileList)
                {
                    using (var reader = new StreamReader(schemaFile))
                    {
                        CompilationUnitNode cuNode;
                        if (Parser.Parse(schemaFile, reader, context, out cuNode))
                        {
                            cuList.Add(cuNode);
                        }
                        else
                        {
                            return false;
                        }
                    }
                }
                var nsList = new List<NamespaceNode>();
                foreach (var cu in cuList)
                {
                    nsList.AddRange(cu.NamespaceList);
                }
                if (nsList.Count == 0)
                {
                    return true;
                }
                var nsInfoMap = new NamespaceInfoMap();
                foreach (var ns in nsList)
                {
                    var uri = ns.UriValue;
                    NamespaceInfo nsInfo;
                    if (!nsInfoMap.TryGetValue(uri, out nsInfo))
                    {
                        nsInfo = new NamespaceInfo(uri);
                        nsInfoMap.Add(uri, nsInfo);
                    }
                    nsInfo.NamespaceNodeList.Add(ns);
                    ns.NamespaceInfo = nsInfo;
                }
                foreach (var ns in nsList)
                {
                    ns.ResolveImports(nsInfoMap);
                }
                foreach (var nsInfo in nsInfoMap.Values)
                {
                    nsInfo.CheckDuplicateGlobalTypeNodes();
                }
                foreach (var ns in nsList)
                {
                    ns.Resolve();
                }
                foreach (var ns in nsList)
                {
                    ns.CreateInfos();
                }
                //
                if (csFileList == null || csFileList.Count == 0)
                {
                    return true;
                }
                var parseOpts = new CSharpParseOptions(preprocessorSymbols: csPpList, documentationMode: DocumentationMode.None);
                var compilation = CSharpCompilation.Create(
                    assemblyName: "__TEMP__",
                    syntaxTrees: csFileList.Select(csFile => CSharpSyntaxTree.ParseText(text: File.ReadAllText(csFile), options: parseOpts, path: csFile)),
                    references: csRefList,
                    options: _csCompilationOptions);
                if (csRefList != null)
                {
                    foreach (var csRef in csRefList)
                    {
                        if (csRef.Properties.Kind == MetadataImageKind.Assembly)
                        {
                            var assSymbol = compilation.GetAssemblyOrModuleSymbol(csRef) as IAssemblySymbol;
                            if (assSymbol != null)
                            {
                                CSEX.MapNamespaces(nsInfoMap, assSymbol, true);
                            }
                        }
                    }
                }
                var compilationAssSymbol = compilation.Assembly;
                if (CSEX.MapNamespaces(nsInfoMap, compilationAssSymbol, false) == 0)
                {
                    return true;
                }
                foreach (var nsInfo in nsInfoMap.Values)
                {
                    if (nsInfo.DottedName == null)
                    {
                        CompilerContext.ErrorAndThrow(new DiagMsgEx(DiagCodeEx.SchemaNamespaceAttributeRequired, nsInfo.Uri), default(TextSpan));
                    }
                }
                CSEX.MapGlobalTypes(nsInfoMap, compilationAssSymbol.GlobalNamespace);
                foreach (var nsInfo in nsInfoMap.Values)
                {
                    nsInfo.SetGlobalTypeDottedNames();
                }
                foreach (var nsInfo in nsInfoMap.Values)
                {
                    nsInfo.MapGlobalTypeMembers();
                }
                var cuAttListSyntaxList = new List<AttributeListSyntax>();
                var cuMemberSyntaxList = new List<MemberDeclarationSyntax>();
                var globalTypeMdRefSyntaxList = new List<ExpressionSyntax>();
                foreach (var nsInfo in nsInfoMap.Values)
                {
                    if (!nsInfo.IsRef)
                    {
                        List<string> dottedPropertyNames;
                        var dottedTypeNames = nsInfo.GetRefData(out dottedPropertyNames);
                        cuAttListSyntaxList.Add(CS.AttributeList("assembly", CSEX.__CompilerSchemaNamespaceAttributeName,
                            SyntaxFactory.AttributeArgument(CS.Literal(nsInfo.Uri)),
                            SyntaxFactory.AttributeArgument(CS.Literal(nsInfo.DottedName.ToString())),
                            SyntaxFactory.AttributeArgument(CS.NewArrOrNullExpr(CS.StringArrayType, dottedTypeNames.Select(i => CS.Literal(i)))),
                            SyntaxFactory.AttributeArgument(CS.NewArrOrNullExpr(CS.StringArrayType, dottedPropertyNames.Select(i => CS.Literal(i))))
                            ));
                        nsInfo.GetSyntax(cuMemberSyntaxList, globalTypeMdRefSyntaxList);
                    }
                }
                var sdataProgramName = CSEX.SDataProgramName(csAssemblyName);
                //>public static class SData_XX  {
                //>  public static void Initialize() { }
                //>  static SData_XX() {
                //>     SData.ProgramMd.AddGlobalTypes(new GlobalTypeMd[]{ ... });
                //>  }
                //>}
                cuMemberSyntaxList.Add(CS.Class(null, CS.PublicStaticTokenList, sdataProgramName, null,
                    CS.Method(CS.PublicStaticTokenList, CS.VoidType, "Initialize", null, null),
                    CS.Constructor(CS.StaticTokenList, sdataProgramName, null, null,
                        CS.ExprStm(CS.InvoExpr(CS.MemberAccessExpr(CSEX.ProgramMdExpr, "AddGlobalTypes"),
                            CS.NewArrOrNullExpr(CSEX.GlobalTypeMdArrayType, globalTypeMdRefSyntaxList))))));
                csCode = _csGeneratedFileBanner +
                    SyntaxFactory.CompilationUnit(default(SyntaxList<ExternAliasDirectiveSyntax>), default(SyntaxList<UsingDirectiveSyntax>),
                        SyntaxFactory.List(cuAttListSyntaxList), SyntaxFactory.List(cuMemberSyntaxList)).NormalizeWhitespace().ToString();

                return true;
            }
            catch (LoadingException) { }
            catch (Exception ex)
            {
                context.AddDiagnostic(DiagnosticSeverity.Error, (int)DiagCodeEx.InternalCompilerError, "Internal compiler error: " + ex.ToString(), default(TextSpan));
            }
            return false;
        }