Esempio n. 1
0
        private SourceCompilerResults compileCore(IProgressMonitor monitor)
        {
            var t0 = System.nanoTime();

            var results      = new SourceCompilerResults();
            var hasErrors    = false;
            var errorManager = new CodeErrorManager();
            var allFiles     = parameters.AllFiles;
            Iterable <IFile> filesToCompile = null;

            try {
                monitor.beginTask("", 11);

                var deletedFiles = parameters.FilesToCompile
                                   .select(p => allFiles.getResource(p))
                                   .where (p => p == null || !p.exists())
                                   .select(p => allFiles.getProjectRelativeName(p)).toSet();
                var typesToCopy = Query.empty <TypeInfo>();

                // Get the files to compile
                if (parameters.FullBuild)
                {
                    filesToCompile = allFiles.getAllResources().where (p => p.exists()).toList();
                }
                else
                {
                    bool filteringDone    = false;
                    var  referencingFiles = parameters.getDependencyInfo().getAllReferencingFiles(parameters.getFilesToCompile());
                    if (parameters.ProgressiveBuild && deletedFiles.isEmpty())
                    {
                        var referencedFiles = parameters.getDependencyInfo().getAllReferencedFiles(parameters.getFilesToCompile());
                        referencedFiles = referencedFiles.except(parameters.getFilesToCompile());
                        referencedFiles = referencedFiles.intersect(referencingFiles);

                        // Progressive build only if referenced and referencing files do not intersect
                        if (!referencedFiles.any())
                        {
                            filesToCompile = parameters.FilesToCompile.select(p => allFiles.getResource(p)).where (p => p.exists()).toList();
                            filteringDone  = true;
                        }
                    }
                    if (!filteringDone)
                    {
                        // Incremental build with dependencies
                        filesToCompile = referencingFiles.select(p => allFiles.getResource(p)).where (p => p.exists()).toList();
                    }

                    var filesToKeep = allFiles.getAllProjectRelativeNames().except(referencingFiles);
                    typesToCopy = filesToKeep.selectMany(p => parameters.DependencyInfo.getFileContents(p))
                                  .where (p => p.indexOf('$') == -1).select(p => parameters.TypeSystem.getType(p));

                    Environment.trace(this, "keeping " + filesToKeep.count() + " files");
                    Environment.trace(this, "ignoring " +
                                      (allFiles.getAllResources().count() - filesToCompile.count() - filesToKeep.count()) + " files");
                }
                Environment.trace(this, "compiling " + filesToCompile.count() + " files");
                monitor.worked(1);
                if (monitor.isCanceled())
                {
                    throw new InterruptedException();
                }

                var compilationUnits = new HashMap <String, CompilationUnitNode>();

                // Parsing
                foreach (var file in filesToCompile)
                {
                    var text = getText(file);
                    if (text != null)
                    {
                        parse(file, text, errorManager, compilationUnits);
                    }
                }
                monitor.worked(1);
                if (monitor.isCanceled())
                {
                    throw new InterruptedException();
                }

                // Compiling
                var t1 = System.nanoTime();

                var typeSystem = new Library(parameters.ClassPath);
                JvmTypeSystemHelper.cloneTypes(typesToCopy, typeSystem);

                var annotatedTypeSystem = new Library(new[] { Environment.getLibraryPath("stabal.jar") }, typeSystem);

                var cparams = new CompilerParameters();
                cparams.TypeSystem          = typeSystem;
                cparams.AnnotatedTypeSystem = annotatedTypeSystem;
                cparams.GenerateClassFiles  = parameters.GenerateClassFiles;
                cparams.ProgressTracker     = new CompilationProgressTracker(monitor);

                var cunits   = compilationUnits.values().toArray(new CompilationUnitNode[compilationUnits.size()]);
                var cresults = new StabCompiler().compileFromCompilationUnits(cparams, cunits);

                Environment.trace(this, "compilation of " + sizeof(cunits) + " files done in " + ((System.nanoTime() - t1) / 1e6) + "ms");

                foreach (var error in cresults.Errors)
                {
                    if (error.Level == 0)
                    {
                        hasErrors = true;
                    }
                    results.CodeErrors.add(error);
                    Environment.trace(this, "error (" + error.Line + ", " + error.Column + ") " + error.Filename + ": " + error.Message);
                }

                if (!hasErrors)
                {
                    var dependencyInfo = new DependencyInfo();
                    results.DependencyInfo = dependencyInfo;
                    var allTypes = new HashSet <String>();

                    // Copy informations from unbuilt files
                    if (parameters.DependencyInfo != null)
                    {
                        var unbuiltFiles = allFiles.getAllProjectRelativeNames();
                        unbuiltFiles = unbuiltFiles.except(filesToCompile.select(p => allFiles.getProjectRelativeName(p)));
                        unbuiltFiles = unbuiltFiles.except(deletedFiles);
                        foreach (var file in unbuiltFiles)
                        {
                            foreach (var type in parameters.DependencyInfo.getFileContents(file))
                            {
                                allTypes.add(type);
                                dependencyInfo.addFileToTypeRelation(file, type);
                                foreach (var refType in parameters.DependencyInfo.getReferencedTypes(type))
                                {
                                    dependencyInfo.addTypeToTypeRelation(type, refType);
                                }
                            }
                        }
                    }

                    // Collect the types and update the dependencies.
                    var typeMembers = new HashMap <IFile, Iterable <TypeMemberNode> >();
                    foreach (var file in filesToCompile)
                    {
                        var fileName        = allFiles.getProjectRelativeName(file);
                        var compilationUnit = compilationUnits[fileName];
                        if (compilationUnit == null)
                        {
                            continue;
                        }
                        var members = SyntaxTreeHelper.getTypeMembers(compilationUnit);
                        typeMembers.put(file, members);
                        foreach (var member in members)
                        {
                            var typeName = member.getUserData(typeof(TypeInfo)).FullName;
                            dependencyInfo.addFileToTypeRelation(fileName, typeName);
                            allTypes.add(typeName);
                        }
                    }

                    if (parameters.DependencyInfo != null)
                    {
                        // Copy the types ignored by this compilation
                        var missingTypes = new HashSet <TypeInfo>();
                        foreach (var t in allTypes.where (p => p.indexOf('$') == -1 && !typeSystem.typeExists(p)))
                        {
                            if (hasErrors = !parameters.DependencyInfo.getReferencedTypes(t).all(p => allTypes.contains(p)))
                            {
                                Environment.trace(this, "Incremental build failed: a type was deleted");
                                break;
                            }
                            missingTypes.add(parameters.TypeSystem.getType(t));
                        }
                        if (!hasErrors)
                        {
                            JvmTypeSystemHelper.cloneTypes(missingTypes, typeSystem);
                        }
                    }

                    if (!hasErrors)
                    {
                        // Compute the dependencies in the compiled files
                        foreach (var member in filesToCompile.select(p => typeMembers[p]).where (p => p != null).selectMany(p => p))
                        {
                            foreach (var t in SyntaxTreeHelper.getTypeMemberDependencies(member)
                                     .intersect(allTypes.select(p => JvmTypeSystemHelper.getType(typeSystem, p))))
                            {
                                dependencyInfo.addTypeToTypeRelation(member.getUserData(typeof(TypeInfo)).FullName, t.FullName);
                            }
                        }

                        results.TypeSystem          = typeSystem;
                        results.AnnotatedTypeSystem = annotatedTypeSystem;
                        foreach (var e in compilationUnits.entrySet())
                        {
                            results.CompilationUnits[e.Key] = e.Value;
                        }
                        foreach (var e in cresults.ClassFiles.entrySet())
                        {
                            results.ClassFiles[e.Key] = e.Value;
                        }
                    }
                }
                monitor.worked(1);
            } catch (CodeErrorException e) {
                monitor.worked(10);
            } catch (TypeLoadException e) {
                results.MissingType = e.TypeName;
                hasErrors           = true;
                monitor.worked(6);
            } finally {
                monitor.done();
            }

            foreach (var file in filesToCompile)
            {
                results.CompiledFiles.add(allFiles.getProjectRelativeName(file));
            }
            foreach (var error in errorManager.Errors)
            {
                if (error.Level == 0)
                {
                    hasErrors = true;
                }
                results.CodeErrors.add(error);
                Environment.trace(this, "error (" + error.Line + ", " + error.Column + ") " + error.Filename + ": " + error.Message);
            }
            results.Failed = hasErrors;

            Environment.trace(this, "compilation done in " + ((System.nanoTime() - t0) / 1e6) + "ms");
            return(results);
        }