Search in sources :

Example 1 with WarningSuppressionVisitor

use of org.eclipse.ceylon.compiler.typechecker.util.WarningSuppressionVisitor in project ceylon by eclipse.

the class JsCompiler method generate.

/**
 * Compile all the phased units in the typechecker.
 * @return true is compilation was successful (0 errors/warnings), false otherwise.
 */
public boolean generate() throws IOException {
    errorVisitor.clear();
    errCount = 0;
    output.clear();
    try {
        if (opts.isVerbose()) {
            logger.debug("Generating metamodel...");
        }
        List<PhasedUnit> typecheckerPhasedUnits = tc.getPhasedUnits().getPhasedUnits();
        List<PhasedUnit> phasedUnits = new ArrayList<>(typecheckerPhasedUnits.size());
        for (PhasedUnit pu : typecheckerPhasedUnits) {
            if (srcFiles == null) {
                phasedUnits.add(pu);
            } else {
                File path = getFullPath(pu);
                if (srcFiles.contains(path)) {
                    phasedUnits.add(pu);
                }
            }
        }
        boolean generatedCode = false;
        // First generate the metamodel
        final Module defmod = tc.getContext().getModules().getDefaultModule();
        for (PhasedUnit pu : phasedUnits) {
            // #416 default module with packages
            Module mod = pu.getPackage().getModule();
            if (mod.getVersion() == null && !mod.isDefaultModule()) {
                // Switch with the default module
                for (org.eclipse.ceylon.model.typechecker.model.Package pkg : mod.getPackages()) {
                    defmod.getPackages().add(pkg);
                    pkg.setModule(defmod);
                }
            }
            EnumSet<Warning> suppressedWarnings = opts.getSuppressWarnings();
            if (suppressedWarnings == null)
                suppressedWarnings = EnumSet.noneOf(Warning.class);
            pu.getCompilationUnit().visit(new WarningSuppressionVisitor<>(Warning.class, suppressedWarnings));
            // Perform capture analysis
            for (org.eclipse.ceylon.model.typechecker.model.Declaration d : pu.getDeclarations()) {
                if (d instanceof TypedDeclaration && d instanceof org.eclipse.ceylon.model.typechecker.model.Setter == false) {
                    pu.getCompilationUnit().visit(new ValueVisitor((TypedDeclaration) d));
                }
            }
            pu.getCompilationUnit().visit(getOutput(pu).mmg);
            if (opts.hasVerboseFlag("ast")) {
                if (opts.getOutWriter() == null) {
                    logger.debug(pu.getCompilationUnit().toString());
                } else {
                    opts.getOutWriter().write(pu.getCompilationUnit().toString());
                    opts.getOutWriter().write('\n');
                }
            }
        }
        // Then write it out and output the reference in the module file
        names = new JsIdentifierNames(this);
        if (!compilingLanguageModule) {
            for (Map.Entry<Module, JsOutput> e : output.entrySet()) {
                e.getValue().encodeModel(names);
            }
        }
        // Output all the require calls for any imports
        final Visitor importVisitor = new Visitor() {

            public void visit(Tree.Import that) {
                ImportableScope scope = that.getImportMemberOrTypeList().getImportList().getImportedScope();
                Module _m = that.getUnit().getPackage().getModule();
                if (scope instanceof Package) {
                    Package pkg = (Package) scope;
                    Module om = pkg.getModule();
                    if (!om.equals(_m) && (!om.isNative() || om.getNativeBackends().supports(Backend.JavaScript))) {
                        Module impmod = ((Package) scope).getModule();
                        if (impmod instanceof NpmAware && ((NpmAware) impmod).getNpmPath() != null) {
                            output.get(_m).requireFromNpm(impmod, names);
                        } else {
                            output.get(_m).require(impmod, names);
                        }
                    }
                }
            }

            public void visit(Tree.ImportModule that) {
                if (that.getImportPath() != null && that.getImportPath().getModel() instanceof Module) {
                    Module m = (Module) that.getImportPath().getModel();
                    // Binary version check goes here now
                    int binMajorVersion = m.getJsMajor();
                    int binMinorVersion = m.getJsMinor();
                    if (m.getJsMajor() == 0) {
                        // Check if it's something we're compiling
                        for (PhasedUnit pu : tc.getPhasedUnits().getPhasedUnits()) {
                            if (pu.getPackage() != null && pu.getPackage().getModule() == m) {
                                m.setJsMajor(Versions.JS_BINARY_MAJOR_VERSION);
                                m.setJsMinor(Versions.JS_BINARY_MINOR_VERSION);
                                binMajorVersion = Versions.JS_BINARY_MAJOR_VERSION;
                                binMinorVersion = Versions.JS_BINARY_MINOR_VERSION;
                                break;
                            }
                        }
                        if (m.getJsMajor() == 0) {
                            // Load the module (most likely we're in the IDE if we need to do this)
                            ArtifactContext ac = new ArtifactContext(null, m.getNameAsString(), m.getVersion(), ArtifactContext.JS_MODEL);
                            ac.setIgnoreDependencies(true);
                            ac.setThrowErrorIfMissing(false);
                            ArtifactResult ar = tc.getContext().getRepositoryManager().getArtifactResult(ac);
                            if (ar == null) {
                                return;
                            }
                            File js = ar.artifact();
                            if (js != null) {
                                Map<String, Object> json = JsModuleSourceMapper.loadJsonModel(js);
                                String binVersion = json.get("$mod-bin").toString();
                                int p = binVersion.indexOf('.');
                                binMajorVersion = Integer.valueOf(binVersion.substring(0, p));
                                binMinorVersion = Integer.valueOf(binVersion.substring(p + 1));
                            }
                        }
                    }
                    if (!Versions.isJsBinaryVersionSupported(binMajorVersion, binMinorVersion)) {
                        that.addError("version '" + m.getVersion() + "' of module '" + m.getNameAsString() + "' was compiled by an incompatible version of the compiler (binary version " + binMajorVersion + "." + binMinorVersion + " of module is not compatible with binary version " + Versions.JS_BINARY_MAJOR_VERSION + "." + Versions.JS_BINARY_MINOR_VERSION + " of this compiler)");
                    }
                }
            }
        };
        for (PhasedUnit pu : phasedUnits) {
            pu.getCompilationUnit().visit(importVisitor);
        }
        // Then generate the JS code
        List<PhasedUnit> pkgs = new ArrayList<>(4);
        if (srcFiles == null && !phasedUnits.isEmpty()) {
            for (PhasedUnit pu : phasedUnits) {
                if ("module.ceylon".equals(pu.getUnitFile().getName())) {
                    final int t = compileUnit(pu);
                    generatedCode = true;
                    if (t != 0) {
                        return false;
                    }
                }
            }
            for (PhasedUnit pu : phasedUnits) {
                if ("package.ceylon".equals(pu.getUnitFile().getName())) {
                    pkgs.add(pu);
                    continue;
                } else if ("module.ceylon".equals(pu.getUnitFile().getName())) {
                    continue;
                }
                final int t = compileUnit(pu);
                generatedCode = true;
                if (t == 1) {
                    return false;
                } else if (t == 2) {
                    break;
                }
            }
        } else if (srcFiles != null && !srcFiles.isEmpty() && // For the specific case of the Stitcher
        !typecheckerPhasedUnits.isEmpty()) {
            for (PhasedUnit pu : phasedUnits) {
                if ("module.ceylon".equals(pu.getUnitFile().getName())) {
                    final int t = compileUnit(pu);
                    generatedCode = true;
                    if (t != 0) {
                        return false;
                    }
                }
            }
            for (File path : srcFiles) {
                if (path.getPath().endsWith(ArtifactContext.JS)) {
                    // Just output the file
                    File dir = path.getParentFile();
                    PhasedUnit lastUnit = phasedUnits.isEmpty() ? typecheckerPhasedUnits.get(0) : phasedUnits.get(0);
                    for (PhasedUnit pu : phasedUnits) {
                        if (pu.getUnitFile().getPath().startsWith(dir.getPath())) {
                            lastUnit = pu;
                            break;
                        }
                    }
                    final JsOutput lastOut = getOutput(lastUnit);
                    VirtualFile vpath = findFile(path);
                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(vpath.getInputStream(), opts.getEncoding()))) {
                        String line = null;
                        while ((line = reader.readLine()) != null) {
                            if (opts.isMinify()) {
                                line = line.trim();
                                if (!opts.isComment() && line.startsWith("//") && !line.contains("*/")) {
                                    continue;
                                }
                            }
                            if (line.length() == 0) {
                                continue;
                            }
                            lastOut.getWriter().write(line);
                            lastOut.getWriter().write('\n');
                        }
                    } finally {
                        lastOut.addSource(path);
                    }
                    generatedCode = true;
                } else {
                    // Find the corresponding compilation unit
                    for (PhasedUnit pu : phasedUnits) {
                        File unitFile = getFullPath(pu);
                        if (path.equals(unitFile)) {
                            if (path.getName().equals("package.ceylon")) {
                                pkgs.add(pu);
                                continue;
                            } else if (path.getName().equals("module.ceylon")) {
                                continue;
                            }
                            final int t = compileUnit(pu);
                            generatedCode = true;
                            if (t == 1) {
                                return false;
                            } else if (t == 2) {
                                break;
                            }
                        }
                    }
                }
            }
            if (resFiles != null) {
                for (Map.Entry<Module, JsOutput> entry : output.entrySet()) {
                    Module module = entry.getKey();
                    final JsOutput lastOut = getOutput(module);
                    for (File file : filterForModule(resFiles, opts.getResourceDirs(), module.getNameAsString())) {
                        String type = Files.probeContentType(file.toPath());
                        String fileName = file.getName();
                        boolean isResourceFile = fileName.endsWith(".properties") || fileName.endsWith(".txt");
                        if (isResourceFile || type != null && type.startsWith("text")) {
                            Writer writer = lastOut.getWriter();
                            writer.write("ex$.");
                            writer.write(resourceKey(module, file));
                            writer.write("=\"");
                            Pattern pattern = Pattern.compile("\\\\|\\t|\\r|\\f|\\n");
                            try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), opts.getEncoding()))) {
                                String line = null;
                                while ((line = reader.readLine()) != null) {
                                    if (isResourceFile && opts.isMinify()) {
                                        line = line.trim();
                                        if (line.length() == 0) {
                                            continue;
                                        }
                                        if (!opts.isComment() && line.startsWith("#")) {
                                            continue;
                                        }
                                    }
                                    StringBuffer result = new StringBuffer();
                                    Matcher matcher = pattern.matcher(line);
                                    while (matcher.find()) {
                                        String escaped;
                                        switch(matcher.group(0)) {
                                            case "\\":
                                                escaped = "\\\\\\\\";
                                                break;
                                            case "\t":
                                                escaped = "\\\\t";
                                                break;
                                            case "\r":
                                                escaped = "\\\\r";
                                                break;
                                            case "\f":
                                                escaped = "\\\\f";
                                                break;
                                            case "\n":
                                                escaped = "\\\\n";
                                                break;
                                            default:
                                                throw new IllegalStateException();
                                        }
                                        matcher.appendReplacement(result, escaped);
                                    }
                                    matcher.appendTail(result);
                                    writer.write(result.toString());
                                    if (reader.ready()) {
                                        writer.write("\\n");
                                    }
                                }
                            }
                            writer.write("\";\n");
                            generatedCode = true;
                        }
                    }
                }
            }
        }
        for (PhasedUnit pu : pkgs) {
            final int t = compileUnit(pu);
            generatedCode = true;
            if (t == 1) {
                return false;
            } else if (t == 2) {
                break;
            }
        }
        if (!generatedCode) {
            logger.error("No source units found to compile");
            exitCode = 2;
        }
    } finally {
        if (exitCode == 0) {
            exitCode = finish();
        }
    }
    return errCount == 0 && exitCode == 0;
}
Also used : VirtualFile(org.eclipse.ceylon.compiler.typechecker.io.VirtualFile) Warning(org.eclipse.ceylon.compiler.typechecker.analyzer.Warning) WarningSuppressionVisitor(org.eclipse.ceylon.compiler.typechecker.util.WarningSuppressionVisitor) Visitor(org.eclipse.ceylon.compiler.typechecker.tree.Visitor) MissingNativeVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.MissingNativeVisitor) Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) ArtifactContext(org.eclipse.ceylon.cmr.api.ArtifactContext) PhasedUnit(org.eclipse.ceylon.compiler.typechecker.context.PhasedUnit) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) ImportableScope(org.eclipse.ceylon.model.typechecker.model.ImportableScope) Pattern(java.util.regex.Pattern) Package(org.eclipse.ceylon.model.typechecker.model.Package) JsIdentifierNames(org.eclipse.ceylon.compiler.js.util.JsIdentifierNames) InputStreamReader(java.io.InputStreamReader) FileInputStream(java.io.FileInputStream) ArtifactResult(org.eclipse.ceylon.model.cmr.ArtifactResult) NpmAware(org.eclipse.ceylon.compiler.js.loader.NpmAware) JsOutput(org.eclipse.ceylon.compiler.js.util.JsOutput) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) BufferedReader(java.io.BufferedReader) Package(org.eclipse.ceylon.model.typechecker.model.Package) Module(org.eclipse.ceylon.model.typechecker.model.Module) VirtualFile(org.eclipse.ceylon.compiler.typechecker.io.VirtualFile) File(java.io.File) Map(java.util.Map) HashMap(java.util.HashMap) Writer(java.io.Writer) FileWriter(java.io.FileWriter)

Aggregations

BufferedReader (java.io.BufferedReader)1 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 FileWriter (java.io.FileWriter)1 InputStreamReader (java.io.InputStreamReader)1 Writer (java.io.Writer)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1 ArtifactContext (org.eclipse.ceylon.cmr.api.ArtifactContext)1 NpmAware (org.eclipse.ceylon.compiler.js.loader.NpmAware)1 JsIdentifierNames (org.eclipse.ceylon.compiler.js.util.JsIdentifierNames)1 JsOutput (org.eclipse.ceylon.compiler.js.util.JsOutput)1 MissingNativeVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.MissingNativeVisitor)1 Warning (org.eclipse.ceylon.compiler.typechecker.analyzer.Warning)1 PhasedUnit (org.eclipse.ceylon.compiler.typechecker.context.PhasedUnit)1 VirtualFile (org.eclipse.ceylon.compiler.typechecker.io.VirtualFile)1 Visitor (org.eclipse.ceylon.compiler.typechecker.tree.Visitor)1