Search in sources :

Example 1 with ModuleDescriptor

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.ModuleDescriptor in project ceylon by eclipse.

the class PhasedUnit method validateTree.

public void validateTree() {
    // System.out.println("Validating tree for " + fileName);
    if (!treeValidated) {
        String fn = unit.getRelativePath();
        for (int i = 0; i < fn.length(); i = fn.offsetByCodePoints(i, 1)) {
            int cp = fn.codePointAt(i);
            if (cp > 127) {
                rootNode.addUsageWarning(Warning.filenameNonAscii, "source file name has non-ASCII characters: " + fn);
            }
        }
        String ufn = unit.getFilename();
        for (Unit u : unit.getPackage().getUnits()) {
            if (!u.equals(unit) && u.getFilename().equalsIgnoreCase(ufn)) {
                if (u.getFilename().equals(ufn)) {
                    String errorMessage = "identical source files: " + unit.getFullPath() + " and " + u.getFullPath();
                    if (u.getFilename().equals(MODULE_FILE) || u.getFilename().equals(PACKAGE_FILE)) {
                        errorMessage += " (a module/package descriptor should be defined only once, even in case of multiple source directories)";
                    }
                    rootNode.addError(errorMessage);
                } else {
                    rootNode.addUsageWarning(Warning.filenameCaselessCollision, "source file names differ only by case: " + unit.getFullPath() + " and " + u.getFullPath());
                }
            }
        }
        rootNode.visit(new Validator().setExceptionHandler(this));
        rootNode.visit(new Visitor() {

            @Override
            public void visit(ModuleDescriptor that) {
                super.visit(that);
                ImportPath importPath = that.getImportPath();
                if (importPath != null) {
                    String moduleName = formatPath(importPath.getIdentifiers());
                    ModuleSourceMapper moduleManagerUtil = moduleSourceMapperRef.get();
                    if (moduleManagerUtil != null) {
                        for (Module otherModule : moduleManagerUtil.getCompiledModules()) {
                            String otherModuleName = otherModule.getNameAsString();
                            if (moduleName.startsWith(otherModuleName + ".") || otherModuleName.startsWith(moduleName + ".")) {
                                StringBuilder error = new StringBuilder().append("Found two modules within the same hierarchy: '").append(otherModule.getNameAsString()).append("' and '").append(moduleName).append("'");
                                that.addError(error.toString());
                            }
                        }
                    }
                }
            }
        }.setExceptionHandler(this));
        treeValidated = true;
    }
}
Also used : ModuleDescriptor(org.eclipse.ceylon.compiler.typechecker.tree.Tree.ModuleDescriptor) DeprecationVisitor(org.eclipse.ceylon.compiler.typechecker.util.DeprecationVisitor) ImportVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.ImportVisitor) TypeHierarchyVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.TypeHierarchyVisitor) LocalDeclarationVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.LocalDeclarationVisitor) StatisticsVisitor(org.eclipse.ceylon.compiler.typechecker.util.StatisticsVisitor) InheritanceVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.InheritanceVisitor) ExpressionVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.ExpressionVisitor) SpecificationVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.SpecificationVisitor) RefinementVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.RefinementVisitor) PrintVisitor(org.eclipse.ceylon.compiler.typechecker.util.PrintVisitor) SelfReferenceVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.SelfReferenceVisitor) TypeArgumentVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.TypeArgumentVisitor) VisibilityVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.VisibilityVisitor) DeclarationVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.DeclarationVisitor) SupertypeVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.SupertypeVisitor) ModuleVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.ModuleVisitor) UsageVisitor(org.eclipse.ceylon.compiler.typechecker.util.UsageVisitor) LiteralVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.LiteralVisitor) Visitor(org.eclipse.ceylon.compiler.typechecker.tree.Visitor) ControlFlowVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.ControlFlowVisitor) TypeVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.TypeVisitor) AnnotationVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.AnnotationVisitor) DefaultTypeArgVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.DefaultTypeArgVisitor) AssertionVisitor(org.eclipse.ceylon.compiler.typechecker.util.AssertionVisitor) AliasVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.AliasVisitor) ImportPath(org.eclipse.ceylon.compiler.typechecker.tree.Tree.ImportPath) ModuleSourceMapper(org.eclipse.ceylon.compiler.typechecker.analyzer.ModuleSourceMapper) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Module(org.eclipse.ceylon.model.typechecker.model.Module) Validator(org.eclipse.ceylon.compiler.typechecker.tree.Validator)

Example 2 with ModuleDescriptor

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.ModuleDescriptor in project ceylon by eclipse.

the class CeylonModelLoader method setupSourceFileObjects.

public static void setupSourceFileObjects(java.util.List<?> treeHolders, final ClassReader reader, final Names names) {
    for (Object treeHolder : treeHolders) {
        if (!(treeHolder instanceof CeylonCompilationUnit)) {
            continue;
        }
        final CeylonCompilationUnit tree = (CeylonCompilationUnit) treeHolder;
        CompilationUnit ceylonTree = tree.ceylonTree;
        final String pkgName = tree.getPackageName() != null ? Util.quoteJavaKeywords(tree.getPackageName().toString()) : "";
        ceylonTree.visit(new SourceDeclarationVisitor() {

            @Override
            public void loadFromSource(Declaration decl) {
                if (!checkNative(decl))
                    return;
                String fqn = Naming.toplevelClassName(pkgName, decl);
                try {
                    reader.enterClass(names.fromString(fqn), tree.getSourceFile());
                    if (Decl.isAnnotationClassNoModel(decl)) {
                        String annotationName = Naming.suffixName(Suffix.$annotation$, fqn);
                        reader.enterClass(names.fromString(annotationName), tree.getSourceFile());
                        if (Decl.isSequencedAnnotationClassNoModel((Tree.AnyClass) decl)) {
                            String annotationsName = Naming.suffixName(Suffix.$annotations$, fqn);
                            reader.enterClass(names.fromString(annotationsName), tree.getSourceFile());
                        }
                    }
                } catch (AssertionError error) {
                // this happens when we have already registered a source file for this decl, hopefully the typechecker
                // will catch this and log an error
                }
            }

            @Override
            public void loadFromSource(ModuleDescriptor that) {
                try {
                    reader.enterClass(names.fromString(pkgName + "." + Naming.MODULE_DESCRIPTOR_CLASS_NAME), tree.getSourceFile());
                } catch (AssertionError error) {
                // this happens when we have already registered a source file for this decl, hopefully the typechecker
                // will catch this and log an error
                }
            }

            @Override
            public void loadFromSource(PackageDescriptor that) {
                try {
                    reader.enterClass(names.fromString(pkgName + "." + Naming.PACKAGE_DESCRIPTOR_CLASS_NAME), tree.getSourceFile());
                } catch (AssertionError error) {
                // this happens when we have already registered a source file for this decl, hopefully the typechecker
                // will catch this and log an error
                }
            }
        });
    }
}
Also used : CeylonCompilationUnit(org.eclipse.ceylon.compiler.java.codegen.CeylonCompilationUnit) CompilationUnit(org.eclipse.ceylon.compiler.typechecker.tree.Tree.CompilationUnit) ModuleDescriptor(org.eclipse.ceylon.compiler.typechecker.tree.Tree.ModuleDescriptor) CeylonCompilationUnit(org.eclipse.ceylon.compiler.java.codegen.CeylonCompilationUnit) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) Declaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Declaration) PackageDescriptor(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PackageDescriptor)

Example 3 with ModuleDescriptor

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.ModuleDescriptor in project ceylon by eclipse.

the class CeylonTransformer method makeDefs.

private List<JCTree> makeDefs(CompilationUnit t) {
    final ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
    t.visit(new SourceDeclarationVisitor() {

        @Override
        public void loadFromSource(Declaration decl) {
            if (!checkNative(decl))
                return;
            Stack<Tree.Declaration> ancestors = new Stack<>();
            long flags = decl instanceof Tree.AnyInterface ? Flags.INTERFACE : 0;
            String name = Naming.toplevelClassName("", decl);
            defs.add(makeClassDef(decl, flags, name, WantedDeclaration.Normal, defs, ancestors));
            if (decl instanceof Tree.AnyInterface) {
                String implName = Naming.getImplClassName(name);
                defs.add(makeClassDef(decl, 0, implName, WantedDeclaration.InterfaceImpl, defs, ancestors));
            }
            if (Decl.isAnnotationClassNoModel(decl)) {
                String annotationName = Naming.suffixName(Suffix.$annotation$, name);
                defs.add(makeClassDef(decl, Flags.ANNOTATION | Flags.INTERFACE, annotationName, WantedDeclaration.Annotation, defs, ancestors));
                if (Decl.isSequencedAnnotationClassNoModel((Tree.AnyClass) decl)) {
                    String annotationsName = Naming.suffixName(Suffix.$annotations$, name);
                    defs.add(makeClassDef(decl, Flags.ANNOTATION | Flags.INTERFACE, annotationsName, WantedDeclaration.AnnotationSequence, defs, ancestors));
                }
            }
        }

        private JCTree makeClassDef(Tree.Declaration decl, long flags, String name, WantedDeclaration wantedDeclaration, ListBuffer<JCTree> toplevelDeclarations, Stack<Tree.Declaration> ancestors) {
            if (decl instanceof Tree.AnyInterface == false && TreeUtil.hasAnnotation(decl.getAnnotationList(), "static", null)) {
                flags |= Flags.STATIC;
            }
            ListBuffer<JCTree.JCTypeParameter> typarams = new ListBuffer<JCTree.JCTypeParameter>();
            if (decl instanceof Tree.ClassOrInterface) {
                Tree.ClassOrInterface classDecl = (ClassOrInterface) decl;
                if (decl instanceof Tree.AnyInterface) {
                    // interfaces are pulled up and catch container type params
                    for (Tree.Declaration ancestor : ancestors) {
                        if (ancestor instanceof Tree.ClassOrInterface) {
                            addTypeParameters(typarams, (Tree.ClassOrInterface) ancestor);
                        }
                    }
                }
                addTypeParameters(typarams, classDecl);
            }
            ancestors.push(decl);
            JCTree ret = make().ClassDef(make().Modifiers(flags | Flags.PUBLIC), names().fromString(name), typarams.toList(), null, List.<JCExpression>nil(), makeClassBody(decl, wantedDeclaration, toplevelDeclarations, ancestors));
            ancestors.pop();
            return ret;
        }

        private void addTypeParameters(ListBuffer<JCTypeParameter> typarams, Tree.ClassOrInterface classDecl) {
            if (classDecl.getTypeParameterList() != null) {
                for (Tree.TypeParameterDeclaration typeParamDecl : classDecl.getTypeParameterList().getTypeParameterDeclarations()) {
                    // we don't need a valid name, just a name, and making it BOGUS helps us find it later if it turns out
                    // we failed to reset everything properly
                    typarams.add(make().TypeParameter(names().fromString("BOGUS-" + typeParamDecl.getIdentifier().getText()), List.<JCExpression>nil()));
                }
            }
        }

        private List<JCTree> makeClassBody(Declaration decl, WantedDeclaration wantedDeclaration, ListBuffer<JCTree> toplevelDeclarations, Stack<Tree.Declaration> ancestors) {
            // only do it for Bootstrap where we control the annotations, because it's so dodgy ATM
            if (wantedDeclaration == WantedDeclaration.Annotation) {
                ListBuffer<JCTree> body = new ListBuffer<JCTree>();
                for (Tree.Parameter param : ((Tree.ClassDefinition) decl).getParameterList().getParameters()) {
                    String name;
                    JCExpression type = make().TypeArray(make().Type(syms().stringType));
                    if (param instanceof Tree.InitializerParameter)
                        name = ((Tree.InitializerParameter) param).getIdentifier().getText();
                    else if (param instanceof Tree.ParameterDeclaration) {
                        Tree.TypedDeclaration typedDeclaration = ((Tree.ParameterDeclaration) param).getTypedDeclaration();
                        name = typedDeclaration.getIdentifier().getText();
                        type = getAnnotationTypeFor(typedDeclaration.getType());
                    } else
                        name = "ERROR";
                    JCMethodDecl method = make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString(name), type, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
                    body.append(method);
                }
                return body.toList();
            }
            if (wantedDeclaration == WantedDeclaration.AnnotationSequence) {
                String name = Naming.toplevelClassName("", decl);
                String annotationName = Naming.suffixName(Suffix.$annotation$, name);
                JCExpression type = make().TypeArray(make().Ident(names().fromString(annotationName)));
                JCMethodDecl method = make().MethodDef(make().Modifiers(Flags.PUBLIC), names().fromString("value"), type, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
                return List.<JCTree>of(method);
            }
            ListBuffer<JCTree> defs = new ListBuffer<>();
            java.util.List<Statement> statements = null;
            if (decl instanceof Tree.ClassDefinition)
                statements = ((Tree.ClassDefinition) decl).getClassBody().getStatements();
            else if (decl instanceof Tree.InterfaceDefinition) {
                // only walk interface members if we're generating the impl class
                if (wantedDeclaration == WantedDeclaration.InterfaceImpl)
                    statements = ((Tree.InterfaceDefinition) decl).getInterfaceBody().getStatements();
            }
            if (statements != null) {
                for (Tree.Statement member : statements) {
                    if (member instanceof Tree.ClassOrInterface && checkNative((Tree.Declaration) member)) {
                        long flags = member instanceof Tree.AnyInterface ? Flags.INTERFACE : 0;
                        String initialName = Naming.toplevelClassName("", (Tree.Declaration) member);
                        String name;
                        if (member instanceof Tree.AnyInterface) {
                            // interfaces are pulled to the toplevel
                            StringBuffer strbuf = new StringBuffer();
                            for (Tree.Declaration part : ancestors) strbuf.append(part.getIdentifier().getText()).append("$");
                            name = strbuf.append(initialName).toString();
                        } else {
                            name = initialName;
                        }
                        JCTree def = makeClassDef((Tree.Declaration) member, flags, name, WantedDeclaration.Normal, toplevelDeclarations, ancestors);
                        if (member instanceof Tree.AnyInterface) {
                            toplevelDeclarations.add(def);
                            String implName = Naming.getImplClassName(initialName);
                            defs.add(makeClassDef((Tree.Declaration) member, 0, implName, WantedDeclaration.InterfaceImpl, defs, ancestors));
                        } else
                            defs.add(def);
                    // FIXME: interfaces impl?
                    }
                }
            }
            return defs.toList();
        }

        private JCExpression getAnnotationTypeFor(Tree.Type type) {
            if (type instanceof Tree.BaseType) {
                String name = ((Tree.BaseType) type).getIdentifier().getText();
                if (name.equals("String") || name.equals("Declaration"))
                    return make().Type(syms().stringType);
                if (name.equals("Boolean"))
                    return make().Type(syms().booleanType);
                if (name.equals("Integer"))
                    return make().Type(syms().longType);
                if (name.equals("Float"))
                    return make().Type(syms().doubleType);
                if (name.equals("Byte"))
                    return make().Type(syms().byteType);
                if (name.equals("Character"))
                    return make().Type(syms().charType);
                if (name.equals("Declaration") || name.equals("ClassDeclaration") || name.equals("InterfaceDeclaration") || name.equals("ClassOrInterfaceDeclaration"))
                    return make().Type(syms().stringType);
                // probably an enum value then
                return make().TypeArray(make().Type(syms().stringType));
            }
            if (type instanceof Tree.SequencedType) {
                return make().TypeArray(getAnnotationTypeFor(((Tree.SequencedType) type).getType()));
            }
            if (type instanceof Tree.SequenceType) {
                return make().TypeArray(getAnnotationTypeFor(((Tree.SequenceType) type).getElementType()));
            }
            if (type instanceof Tree.IterableType) {
                return make().TypeArray(getAnnotationTypeFor(((Tree.IterableType) type).getElementType()));
            }
            if (type instanceof Tree.TupleType) {
                // can only be one, must be a SequencedType
                Tree.Type sequencedType = ((Tree.TupleType) type).getElementTypes().get(0);
                return getAnnotationTypeFor(sequencedType);
            }
            System.err.println("Unknown Annotation type: " + type);
            return make().TypeArray(make().Type(syms().stringType));
        }

        @Override
        public void loadFromSource(ModuleDescriptor that) {
        // don't think we care about these
        }

        @Override
        public void loadFromSource(PackageDescriptor that) {
        // don't think we care about these
        }
    });
    return defs.toList();
}
Also used : ClassOrInterface(org.eclipse.ceylon.compiler.typechecker.tree.Tree.ClassOrInterface) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) SourceDeclarationVisitor(org.eclipse.ceylon.compiler.java.loader.SourceDeclarationVisitor) List(org.eclipse.ceylon.langtools.tools.javac.util.List) Declaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Declaration) JCMethodDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCMethodDecl) Stack(java.util.Stack) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) PackageDescriptor(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PackageDescriptor) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Declaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Declaration) ClassOrInterface(org.eclipse.ceylon.compiler.typechecker.tree.Tree.ClassOrInterface) Statement(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Statement) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) ModuleDescriptor(org.eclipse.ceylon.compiler.typechecker.tree.Tree.ModuleDescriptor) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter)

Example 4 with ModuleDescriptor

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.ModuleDescriptor in project ceylon by eclipse.

the class PhasedUnitsModuleManager method initTypeCheckedUnits.

private void initTypeCheckedUnits() {
    for (PhasedUnit unit : getPhasedUnits().getPhasedUnits()) {
        // obtain the unit container path
        final String pkgName = Util.getUnitPackageName(unit);
        unit.getCompilationUnit().visit(new SourceDeclarationVisitor() {

            @Override
            public void loadFromSource(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Declaration decl) {
                compiledClasses.add(Util.getQuotedFQN(pkgName, decl));
            }

            @Override
            public void loadFromSource(ModuleDescriptor that) {
            // don't think we care about these
            }

            @Override
            public void loadFromSource(PackageDescriptor that) {
            // don't think we care about these
            }
        });
    }
}
Also used : ModuleDescriptor(org.eclipse.ceylon.compiler.typechecker.tree.Tree.ModuleDescriptor) SourceDeclarationVisitor(org.eclipse.ceylon.compiler.java.loader.SourceDeclarationVisitor) PackageDescriptor(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PackageDescriptor) PhasedUnit(org.eclipse.ceylon.compiler.typechecker.context.PhasedUnit)

Aggregations

ModuleDescriptor (org.eclipse.ceylon.compiler.typechecker.tree.Tree.ModuleDescriptor)4 PackageDescriptor (org.eclipse.ceylon.compiler.typechecker.tree.Tree.PackageDescriptor)3 SourceDeclarationVisitor (org.eclipse.ceylon.compiler.java.loader.SourceDeclarationVisitor)2 Declaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Declaration)2 Stack (java.util.Stack)1 CeylonCompilationUnit (org.eclipse.ceylon.compiler.java.codegen.CeylonCompilationUnit)1 AliasVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.AliasVisitor)1 AnnotationVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.AnnotationVisitor)1 ControlFlowVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.ControlFlowVisitor)1 DeclarationVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.DeclarationVisitor)1 DefaultTypeArgVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.DefaultTypeArgVisitor)1 ExpressionVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.ExpressionVisitor)1 ImportVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.ImportVisitor)1 InheritanceVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.InheritanceVisitor)1 LiteralVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.LiteralVisitor)1 LocalDeclarationVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.LocalDeclarationVisitor)1 ModuleSourceMapper (org.eclipse.ceylon.compiler.typechecker.analyzer.ModuleSourceMapper)1 ModuleVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.ModuleVisitor)1 RefinementVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.RefinementVisitor)1 SelfReferenceVisitor (org.eclipse.ceylon.compiler.typechecker.analyzer.SelfReferenceVisitor)1