//
        // Analyze the input files based on the compiler cache files.
        //
        // Put the analyze result in _analyzeResult and other related data fields,
        // such as RecompileMarkupPages, RecompileApplicationFile, etc.
        //
        // If analyze is failed somehow, throw exception.
        //
        internal void AnalyzeInputFiles()
        {
            //
            // First: Detect if the entire project requires re-compile.
            //

            //
            // If the compiler state file doesn't exist, recompile all the xaml files.
            //
            if (!CompilerState.StateFileExists())
            {
                _analyzeResult = RecompileCategory.All;
            }
            else
            {
                // Load the compiler state file.
                CompilerState.LoadStateInformation();

                // if PresenationBuildTasks.dll is changed last build, rebuild the entire project for sure.

                if (IsFileChanged(Assembly.GetExecutingAssembly().Location) ||
                    IsFileListChanged(_mcPass1.ExtraBuildControlFiles))
                {
                    _analyzeResult = RecompileCategory.All;
                }
                else
                {
                    //
                    // Any one single change in below list would request completely re-compile.
                    //
                    if (IsSettingModified(CompilerState.References, _mcPass1.ReferencesCache) ||
                        IsSettingModified(CompilerState.ApplicationFile, _mcPass1.ApplicationFile) ||
                        IsSettingModified(CompilerState.RootNamespace, _mcPass1.RootNamespace) ||
                        IsSettingModified(CompilerState.AssemblyName, _mcPass1.AssemblyName) ||
                        IsSettingModified(CompilerState.AssemblyVersion, _mcPass1.AssemblyVersion) ||
                        IsSettingModified(CompilerState.AssemblyPublicKeyToken, _mcPass1.AssemblyPublicKeyToken) ||
                        IsSettingModified(CompilerState.OutputType, _mcPass1.OutputType) ||
                        IsSettingModified(CompilerState.Language, _mcPass1.Language) ||
                        IsSettingModified(CompilerState.LanguageSourceExtension, _mcPass1.LanguageSourceExtension) ||
                        IsSettingModified(CompilerState.OutputPath, _mcPass1.OutputPath) ||
                        IsSettingModified(CompilerState.LocalizationDirectivesToLocFile, _mcPass1.LocalizationDirectivesToLocFile))
                    {
                        _analyzeResult = RecompileCategory.All;
                    }
                    else
                    {
                        if (_mcPass1.IsApplicationTarget)
                        {
                            //
                            // When application definition file is modified, it could potentially change the application
                            // class name, it then has impact on all other xaml file compilation, so recompile the entire
                            // project for this case.
                            //
                            if (TaskFileService.Exists(_mcPass1.ApplicationFile) && IsFileChanged(_mcPass1.ApplicationFile))
                            {
                                _analyzeResult = RecompileCategory.All;
                            }
                        }

                        //
                        // If any one referenced assembly is updated since last build, the entire project needs to recompile.
                        //

                        if (IsFileListChanged(_mcPass1.References))
                        {
                            _analyzeResult = RecompileCategory.All;
                        }
                    }
                }
            }

            if (_analyzeResult == RecompileCategory.All)
            {
                UpdateFileListForCleanbuild();
                return;
            }

            //
            // The entire project recompilation should have already been handled when code goes here.
            // Now, Detect the individual xaml files which require to recompile.
            //

            if (_mcPass1.IsApplicationTarget)
            {
                if (IsSettingModified(CompilerState.ContentFiles, _mcPass1.ContentFilesCache))
                {
                    _analyzeResult |= RecompileCategory.ContentFiles;
                }

                // if HostInBrowser setting is changed, it would affect the application file compilation only.
                if (IsSettingModified(CompilerState.HostInBrowser, _mcPass1.HostInBrowser))
                {
                    _analyzeResult |= RecompileCategory.ApplicationFile;
                }

                if (IsSettingModified(CompilerState.SplashImage, _mcPass1.SplashImageName))
                {
                    _analyzeResult |= RecompileCategory.ApplicationFile;
                }
            }

            //
            // If code files are changed, or Define flags are changed, it would affect the xaml file with local types.
            //
            // If previous build didn't have such local-ref-xaml files, don't bother to do further check for this.
            //

            if (CompilerLocalReference.CacheFileExists())
            {
                if (IsSettingModified(CompilerState.DefineConstants, _mcPass1.DefineConstants) ||
                    IsSettingModified(CompilerState.SourceCodeFiles, _mcPass1.SourceCodeFilesCache) ||
                    IsFileListChanged(_mcPass1.SourceCodeFiles))
                {
                    _analyzeResult |= RecompileCategory.PagesWithLocalType;
                }
            }

            List <FileUnit> modifiedXamlFiles = new List <FileUnit>();

            //
            // Detect if any .xaml page is updated since last build
            //
            if (ListIsNotEmpty(_mcPass1.PageMarkup))
            {
                //
                // If the PageMarkup file number or hashcode is changed, it would affect
                // the xaml files with local types.
                //
                // This check is necessary for the senario that a xaml file is removed and the
                // removed xaml file could be referenced by other xaml files with local types.
                //
                if (IsSettingModified(CompilerState.PageMarkup, _mcPass1.PageMarkupCache))
                {
                    if (CompilerLocalReference.CacheFileExists())
                    {
                        _analyzeResult |= RecompileCategory.PagesWithLocalType;
                    }
                }

                // Below code detects which invidual xaml files are modified since last build.
                for (int i = 0; i < _mcPass1.PageMarkup.Length; i++)
                {
                    ITaskItem taskItem    = _mcPass1.PageMarkup[i];
                    string    fileName    = taskItem.ItemSpec;
                    string    filepath    = Path.GetFullPath(fileName);
                    string    linkAlias   = taskItem.GetMetadata(SharedStrings.Link);
                    string    logicalName = taskItem.GetMetadata(SharedStrings.LogicalName);

                    if (IsFileChanged(filepath))
                    {
                        // add this file to the modified file list.
                        modifiedXamlFiles.Add(new FileUnit(filepath, linkAlias, logicalName));
                    }
                    else
                    {
                        // A previously generated xaml file (with timestamp earlier than of the cache file)
                        // could be added to the project.  This means that the above check for time stamp
                        // will skip compiling the newly added xaml file.  We save the name all the xaml
                        // files we previously built to the cache file.  Retrieve that list and see if
                        // this xaml file is already in it.  If so, we'll skip compiling this xaml file,
                        // else, this xaml file was just added to the project and thus compile it.

                        if (!CompilerState.PageMarkupFileNames.Contains(fileName))
                        {
                            modifiedXamlFiles.Add(new FileUnit(filepath, linkAlias, logicalName));
                        }
                    }
                }

                if (modifiedXamlFiles.Count > 0)
                {
                    _analyzeResult |= RecompileCategory.ModifiedPages;

                    if (CompilerLocalReference.CacheFileExists())
                    {
                        _analyzeResult |= RecompileCategory.PagesWithLocalType;
                    }
                }
            }

            // Check for the case where a required Pass2 wasn't run, e.g. because the build was aborted,
            // or because the Compile target was run inside VS.
            // If that happened, let's recompile the local-type pages, which will force Pass2 to run.
            if (CompilerState.Pass2Required && CompilerLocalReference.CacheFileExists())
            {
                _analyzeResult |= RecompileCategory.PagesWithLocalType;
            }

            UpdateFileListForIncrementalBuild(modifiedXamlFiles);
        }
        //
        // Generate new list of files that require to recompile for incremental build based on _analyzeResult
        //
        private void UpdateFileListForIncrementalBuild(List <FileUnit> modifiedXamlFiles)
        {
            List <FileUnit> recompiledXaml    = new List <FileUnit>();
            bool            recompileApp      = false;
            int             numLocalTypeXamls = 0;

            if ((_analyzeResult & RecompileCategory.ContentFiles) == RecompileCategory.ContentFiles)
            {
                RecompileContentFiles();
            }

            if ((_analyzeResult & RecompileCategory.ApplicationFile) == RecompileCategory.ApplicationFile)
            {
                recompileApp = true;
            }

            if ((_analyzeResult & RecompileCategory.PagesWithLocalType) == RecompileCategory.PagesWithLocalType && TaskFileService.IsRealBuild)
            {
                CompilerLocalReference.LoadCacheFile();

                if (CompilerLocalReference.LocalApplicationFile != null)
                {
                    // Application file contains local types, it will be recompiled.
                    recompileApp = true;
                }

                if (ListIsNotEmpty(CompilerLocalReference.LocalMarkupPages))
                {
                    numLocalTypeXamls = CompilerLocalReference.LocalMarkupPages.Length;

                    for (int i = 0; i < CompilerLocalReference.LocalMarkupPages.Length; i++)
                    {
                        LocalReferenceFile localRefFile = CompilerLocalReference.LocalMarkupPages[i];
                        recompiledXaml.Add(new FileUnit(
                                               localRefFile.FilePath,
                                               localRefFile.LinkAlias,
                                               localRefFile.LogicalName));
                    }
                }
            }

            if ((_analyzeResult & RecompileCategory.ModifiedPages) == RecompileCategory.ModifiedPages)
            {
                // If the xaml is already in the local-type-ref xaml file list, don't add a duplicate file path to recompiledXaml list.

                for (int i = 0; i < modifiedXamlFiles.Count; i++)
                {
                    FileUnit xamlfile = modifiedXamlFiles[i];
                    bool     addToList;

                    addToList = true;

                    if (numLocalTypeXamls > 0)
                    {
                        for (int j = 0; j < numLocalTypeXamls; j++)
                        {
                            if (String.Compare(xamlfile.Path, CompilerLocalReference.LocalMarkupPages[j].FilePath, StringComparison.OrdinalIgnoreCase) == 0)
                            {
                                addToList = false;
                                break;
                            }
                        }
                    }

                    if (addToList)
                    {
                        recompiledXaml.Add(xamlfile);
                    }
                }
            }

            if (recompiledXaml.Count > 0)
            {
                _recompileMarkupPages = recompiledXaml.ToArray();
            }

            // Set ApplicationFile appropriatelly for this incremental build.
            ProcessApplicationFile(recompileApp);
        }
Exemplo n.º 3
0
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

        #region Public Methods

        /// <summary>
        /// Execute method in Task
        /// </summary>
        /// <returns></returns>
        public override bool Execute()
        {

            //CASRemoval:(new PermissionSet(PermissionState.Unrestricted)).Assert();

            TaskHelper.DisplayLogo(Log, SR.Get(SRID.MarkupCompilePass1Task));

            bool bSuccess = true;

            try
            {

                //
                // Create the TaskFileService instance here
                //

                _taskFileService = new TaskFileService(this) as ITaskFileService;

                _compilerState = new CompilerState(
                    OutputPath + AssemblyName + (TaskFileService.IsRealBuild? SharedStrings.StateFile : SharedStrings.IntellisenseStateFile),
                    TaskFileService);

                _compilerLocalRefCache = new CompilerLocalReference(
                    OutputPath + AssemblyName + (TaskFileService.IsRealBuild? SharedStrings.LocalTypeCacheFile : SharedStrings.IntellisenseLocalTypeCacheFile),
                    TaskFileService);

                if ((PageMarkup == null || PageMarkup.Length == 0) &&
                    (ApplicationMarkup == null || ApplicationMarkup.Length == 0))
                {
                    // Don't need to do further work.
                    // stop here.
                    CleanupCacheFiles();
                    return true;
                }

                VerifyInputs();

                Log.LogMessageFromResources(MessageImportance.Low, SRID.CurrentDirectory, SourceDir);

                // If wrong files are set to some properties, the task
                // should stop here immediatelly.

                if (_nErrors > 0)
                {
                    Log.LogErrorWithCodeFromResources(SRID.WrongPropertySetting);
                }
                else
                {

                    // create output directory
                    if (!Directory.Exists(OutputPath))
                    {
                        Directory.CreateDirectory(OutputPath);
                    }

                    // Analyze project inputs to detect which xaml files require to recompile.
                    AnalyzeInputsAndSetting();

                    Log.LogMessageFromResources(MessageImportance.Low, SRID.AnalysisResult, CompilerAnalyzer.AnalyzeResult);

                    if (!SkipMarkupCompilation)
                    {

                        if (CompilerAnalyzer.RecompileMarkupPages != null)
                        {
                            for (int i = 0; i < CompilerAnalyzer.RecompileMarkupPages.Length; i++)
                            {

                                Log.LogMessageFromResources(MessageImportance.Low, SRID.RecompiledXaml, CompilerAnalyzer.RecompileMarkupPages[i]);
                            }
                        }

                        // If recompile is required, CompilerAnalyzer contains all the files which need to recompile.

                        // Cleanup baml files and code files generated in previous build.
                        if (TaskFileService.IsRealBuild)
                        {
                            CleanupGeneratedFiles();
                        }

                        // Call the Markup Compiler to do the real compiling work
                        DoMarkupCompilation();
                    }


                    // Generate the required output items.
                    GenerateOutputItems();

                    Log.LogMessageFromResources(MessageImportance.Low, SRID.CompilationDone);
                }

            }
#pragma warning disable 6500
            catch (Exception e)
            {
                string message;
                string errorId;

                errorId = Log.ExtractMessageCode(e.Message, out message);

                if (String.IsNullOrEmpty(errorId))
                {
                    errorId = UnknownErrorID;
                    message = SR.Get(SRID.UnknownBuildError, message);
                }

                Log.LogError(null, errorId, null, null, 0, 0, 0, 0, message, null);

                _nErrors++;
            }
            catch // Non-CLS compliant errors
            {
                Log.LogErrorWithCodeFromResources(SRID.NonClsError);
                _nErrors++;
            }
#pragma warning restore 6500

            if (_nErrors > 0)
            {
                // When error counter is changed, the appropriate error message should have
                // been reported, simply return false here.
                bSuccess = false;
                CleanupCacheFiles();
            }
            else
            {
                Log.LogMessageFromResources(MessageImportance.Low, SRID.CompileSucceed_Pass1);
            }

            return bSuccess;
        }
        //------------------------------------------------------
        //
        // Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        //
        // Initialze the local xaml cache file.
        //
        // return value:
        //
        //    If cache doesn't exist, or both LocalAppDef and LocallXaml Pages do not exist, return false
        //    to indicate no further work required.
        //    otherwise, return true.
        //
        private bool InitLocalXamlCache()
        {
            bool hasLocalFiles = false;

            _compilerLocalRefCache = new CompilerLocalReference(
                         OutputPath + AssemblyName + (TaskFileService.IsRealBuild? SharedStrings.LocalTypeCacheFile : SharedStrings.IntellisenseLocalTypeCacheFile),
                        _taskFileService);

            if (_compilerLocalRefCache.CacheFileExists())
            {
                _compilerLocalRefCache.LoadCacheFile();

                _localApplicationFile = _compilerLocalRefCache.LocalApplicationFile;
                _localMarkupPages = _compilerLocalRefCache.LocalMarkupPages;

                if (_localApplicationFile != null || (_localMarkupPages != null && _localMarkupPages.Length > 0))
                {
                    hasLocalFiles = true;

                    //
                    // Initialize InternalTypeHelper file from the cache file first.
                    // Further handling will be taken after the xaml file compilation is done.
                    //
                    // If InternalTypeHelperFile is set in the Cache file, it means Pass1 cannot
                    // detect whether or not to keep the InternalTypeHelper File until the Pass2
                    // xaml file compilation is done.
                    //
                    _internalTypeHelperFile = _compilerLocalRefCache.InternalTypeHelperFile;
                }
            }

            return hasLocalFiles;
        }
Exemplo n.º 5
0
        //
        // Generate new list of files that require to recompile for incremental build based on _analyzeResult
        //
        private void UpdateFileListForIncrementalBuild(List <FileUnit> modifiedXamlFiles)
        {
            List <FileUnit> recompiledXaml    = new List <FileUnit>();
            bool            recompileApp      = false;
            int             numLocalTypeXamls = 0;

            if ((_analyzeResult & RecompileCategory.ContentFiles) == RecompileCategory.ContentFiles)
            {
                RecompileContentFiles();
            }

            if ((_analyzeResult & RecompileCategory.ApplicationFile) == RecompileCategory.ApplicationFile)
            {
                recompileApp = true;
            }

            if ((_analyzeResult & RecompileCategory.PagesWithLocalType) == RecompileCategory.PagesWithLocalType && TaskFileService.IsRealBuild)
            {
                CompilerLocalReference.LoadCacheFile();

                if (CompilerLocalReference.LocalApplicationFile != null)
                {
                    // Application file contains local types, it will be recompiled.
                    recompileApp = true;
                }

                if (ListIsNotEmpty(CompilerLocalReference.LocalMarkupPages))
                {
                    numLocalTypeXamls = CompilerLocalReference.LocalMarkupPages.Length;

                    // Under incremental builds of SDK projects, we can have a state where the cache contains some XAML files but the Page blob
                    // no longer contains them.  To avoid attempting to recompile a file that no longer exists, ensure that any cached XAML file
                    // still exists in the Page blob prior to queuing it up for recompilation.
                    HashSet <string> localMarkupPages = new HashSet <string>(_mcPass1.PageMarkup.Select(x => x.GetMetadata(SharedStrings.FullPath)), StringComparer.OrdinalIgnoreCase);

                    for (int i = 0; i < numLocalTypeXamls; i++)
                    {
                        LocalReferenceFile localRefFile = CompilerLocalReference.LocalMarkupPages[i];

                        if (localMarkupPages.Contains(localRefFile.FilePath))
                        {
                            recompiledXaml.Add(new FileUnit(
                                                   localRefFile.FilePath,
                                                   localRefFile.LinkAlias,
                                                   localRefFile.LogicalName));
                        }
                    }
                }
            }

            if ((_analyzeResult & RecompileCategory.ModifiedPages) == RecompileCategory.ModifiedPages)
            {
                // If the xaml is already in the local-type-ref xaml file list, don't add a duplicate file path to recompiledXaml list.

                for (int i = 0; i < modifiedXamlFiles.Count; i++)
                {
                    FileUnit xamlfile = modifiedXamlFiles[i];
                    bool     addToList;

                    addToList = true;

                    if (numLocalTypeXamls > 0)
                    {
                        for (int j = 0; j < numLocalTypeXamls; j++)
                        {
                            if (String.Compare(xamlfile.Path, CompilerLocalReference.LocalMarkupPages[j].FilePath, StringComparison.OrdinalIgnoreCase) == 0)
                            {
                                addToList = false;
                                break;
                            }
                        }
                    }

                    if (addToList)
                    {
                        recompiledXaml.Add(xamlfile);
                    }
                }
            }

            if (recompiledXaml.Count > 0)
            {
                _recompileMarkupPages = recompiledXaml.ToArray();
            }

            // Set ApplicationFile appropriatelly for this incremental build.
            ProcessApplicationFile(recompileApp);
        }