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;
}
}
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
}
}
});
}
}
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();
}
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
}
});
}
}
Aggregations