use of org.eclipse.ceylon.model.typechecker.model.TypeAlias in project ceylon by eclipse.
the class AnnotationVisitor method visit.
@Override
public void visit(Tree.DocLink that) {
super.visit(that);
String text = that.getText();
int pipeIndex = text.indexOf("|");
if (pipeIndex != -1) {
text = text.substring(pipeIndex + 1);
}
String kind = null;
if (text.startsWith(DOC_LINK_MODULE)) {
kind = DOC_LINK_MODULE;
text = text.substring(DOC_LINK_MODULE.length());
} else if (text.startsWith(DOC_LINK_PACKAGE)) {
kind = DOC_LINK_PACKAGE;
text = text.substring(DOC_LINK_PACKAGE.length());
} else if (text.startsWith(DOC_LINK_CLASS)) {
kind = DOC_LINK_CLASS;
text = text.substring(DOC_LINK_CLASS.length());
} else if (text.startsWith(DOC_LINK_INTERFACE)) {
kind = DOC_LINK_INTERFACE;
text = text.substring(DOC_LINK_INTERFACE.length());
} else if (text.startsWith(DOC_LINK_FUNCTION)) {
kind = DOC_LINK_FUNCTION;
text = text.substring(DOC_LINK_FUNCTION.length());
} else if (text.startsWith(DOC_LINK_VALUE)) {
kind = DOC_LINK_VALUE;
text = text.substring(DOC_LINK_VALUE.length());
} else if (text.startsWith(DOC_LINK_ALIAS)) {
kind = DOC_LINK_ALIAS;
text = text.substring(DOC_LINK_ALIAS.length());
}
boolean parentheses = false;
if (text.endsWith("()")) {
parentheses = true;
text = text.substring(0, text.length() - 2);
}
int scopeIndex = text.indexOf("::");
String packageName;
if (DOC_LINK_MODULE.equals(kind) || DOC_LINK_PACKAGE.equals(kind)) {
packageName = text;
} else {
packageName = scopeIndex < 0 ? null : text.substring(0, scopeIndex);
}
String path = scopeIndex < 0 ? text : text.substring(scopeIndex + 2);
String[] names = path.isEmpty() ? new String[0] : path.split("\\.");
Declaration base = null;
if (packageName == null) {
if (names.length > 0) {
base = that.getScope().getMemberOrParameter(that.getUnit(), names[0], null, false);
}
} else {
Package pack = that.getUnit().getPackage().getModule().getPackage(packageName);
if (pack == null) {
if (DOC_LINK_MODULE.equals(kind)) {
that.addUsageWarning(Warning.doclink, "module is missing: '" + packageName + "'");
} else {
that.addUsageWarning(Warning.doclink, "package is missing: '" + packageName + "'");
}
} else {
that.setPkg(pack);
if (DOC_LINK_MODULE.equals(kind)) {
Package rootPack = pack.getModule().getRootPackage();
if (pack.equals(rootPack)) {
that.setModule(pack.getModule());
} else {
that.addUsageWarning(Warning.doclink, "module is missing: '" + packageName + "'");
}
}
if (names.length > 0) {
base = pack.getDirectMember(names[0], null, false);
}
}
if (DOC_LINK_MODULE.equals(kind) || DOC_LINK_PACKAGE.equals(kind)) {
return;
}
}
if (base == null) {
that.addUsageWarning(Warning.doclink, "declaration is missing: '" + (names.length > 0 ? names[0] : text) + "'");
} else {
that.setBase(base);
if (names.length > 1) {
that.setQualified(new ArrayList<Declaration>(names.length - 1));
}
for (int i = 1; i < names.length; i++) {
if (base instanceof Value) {
Value value = (Value) base;
if (!value.isParameter() && !value.isTransient() && value.getTypeDeclaration() != null && value.getTypeDeclaration().isAnonymous()) {
base = value.getTypeDeclaration();
}
}
if (base instanceof TypeDeclaration || base instanceof Functional) {
Declaration qualified = base.getMember(names[i], null, false);
if (qualified == null) {
that.addUsageWarning(Warning.doclink, "member declaration or parameter is missing: '" + names[i] + "'");
break;
} else {
that.getQualified().add(qualified);
base = qualified;
}
} else {
that.addUsageWarning(Warning.doclink, "not a type or functional declaration: '" + base.getName() + "'");
break;
}
}
}
if (base != null) {
if (kind != null && (names.length == 1 || names.length == that.getQualified().size() + 1)) {
if (DOC_LINK_CLASS.equals(kind) && !(base instanceof Class)) {
that.addUsageWarning(Warning.doclink, "linked declaration is not a class: '" + base.getName() + "'");
} else if (DOC_LINK_INTERFACE.equals(kind) && !(base instanceof Interface)) {
that.addUsageWarning(Warning.doclink, "linked declaration is not an interface: '" + base.getName() + "'");
} else if (DOC_LINK_ALIAS.equals(kind) && !(base instanceof TypeAlias)) {
that.addUsageWarning(Warning.doclink, "linked declaration is not a type alias: '" + base.getName() + "'");
} else if (DOC_LINK_FUNCTION.equals(kind) && !(base instanceof Function)) {
that.addUsageWarning(Warning.doclink, "linked declaration is not a function: '" + base.getName() + "'");
} else if (DOC_LINK_VALUE.equals(kind) && !(base instanceof Value)) {
that.addUsageWarning(Warning.doclink, "linked declaration is not a value: '" + base.getName() + "'");
}
}
if (parentheses && !(base instanceof Functional)) {
that.addUsageWarning(Warning.doclink, "linked declaration is not a function: '" + base.getName() + "'");
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeAlias in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.TypeLiteral that) {
if (that instanceof Tree.InterfaceLiteral || that instanceof Tree.ClassLiteral || that instanceof Tree.NewLiteral || that instanceof Tree.AliasLiteral || that instanceof Tree.TypeParameterLiteral) {
declarationLiteral = true;
} else {
modelLiteral = true;
}
try {
super.visit(that);
} finally {
declarationLiteral = false;
modelLiteral = false;
}
Type t;
TypeDeclaration d;
Tree.StaticType type = that.getType();
Node errorNode;
if (type != null) {
t = type.getTypeModel();
d = t.getDeclaration();
errorNode = type;
} else {
errorNode = that;
ClassOrInterface classOrInterface = getContainingClassOrInterface(that.getScope());
if (that instanceof Tree.ClassLiteral || that instanceof Tree.InterfaceLiteral) {
d = classOrInterface;
if (d == null) {
errorNode.addError("no containing type");
// EARLY EXIT!!
return;
} else {
t = classOrInterface.getType();
}
} else {
errorNode.addError("missing type reference");
// EARLY EXIT!!
return;
}
}
if (t != null) {
that.setDeclaration(d);
that.setWantsDeclaration(true);
if (that instanceof Tree.ClassLiteral) {
if (!(d instanceof Class)) {
if (d != null) {
errorNode.addError("referenced declaration is not a class" + getDeclarationReferenceSuggestion(d));
}
that.setTypeModel(unit.getClassDeclarationType());
} else {
that.setTypeModel(unit.getClassDeclarationType((Class) d));
}
} else if (that instanceof Tree.NewLiteral) {
if (d instanceof Class) {
Class c = (Class) d;
Constructor defaultConstructor = c.getDefaultConstructor();
if (defaultConstructor != null) {
d = defaultConstructor;
}
}
if (d instanceof Constructor) {
Constructor c = (Constructor) d;
if (c.getParameterList() == null) {
that.setTypeModel(unit.getValueConstructorDeclarationType());
} else {
that.setTypeModel(unit.getCallableConstructorDeclarationType());
}
} else if (d != null) {
errorNode.addError("referenced declaration is not a constructor" + getDeclarationReferenceSuggestion(d));
}
} else if (that instanceof Tree.InterfaceLiteral) {
if (!(d instanceof Interface)) {
if (d != null) {
errorNode.addError("referenced declaration is not an interface" + getDeclarationReferenceSuggestion(d));
}
}
that.setTypeModel(unit.getInterfaceDeclarationType());
} else if (that instanceof Tree.AliasLiteral) {
if (!(d instanceof TypeAlias)) {
errorNode.addError("referenced declaration is not a type alias" + getDeclarationReferenceSuggestion(d));
}
that.setTypeModel(unit.getAliasDeclarationType());
} else if (that instanceof Tree.TypeParameterLiteral) {
if (!(d instanceof TypeParameter)) {
errorNode.addError("referenced declaration is not a type parameter" + getDeclarationReferenceSuggestion(d));
}
that.setTypeModel(unit.getTypeParameterDeclarationType());
} else if (d != null) {
that.setWantsDeclaration(false);
t = t.resolveAliases();
if (t == null || t.isUnknown()) {
return;
}
// checkNonlocalType(that.getType(), t.getDeclaration());
if (d instanceof Constructor) {
if (((Constructor) d).isAbstraction()) {
errorNode.addError("constructor is overloaded");
} else {
that.setTypeModel(unit.getConstructorMetatype(t));
}
} else if (d instanceof Class) {
// checkNonlocal(that, t.getDeclaration());
that.setTypeModel(unit.getClassMetatype(t));
} else if (d instanceof Interface) {
that.setTypeModel(unit.getInterfaceMetatype(t));
} else {
that.setTypeModel(unit.getTypeMetaType(t));
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeAlias in project ceylon by eclipse.
the class GenerateJsVisitor method visit.
@Override
public void visit(final Tree.TypeAliasDeclaration that) {
// Don't even bother with nodes that have errors
if (errVisitor.hasErrors(that))
return;
final TypeAlias d = that.getDeclarationModel();
if (opts.isOptimize() && d.isClassOrInterfaceMember())
return;
comment(that);
final String tname = names.createTempVariable();
out(function, names.name(d), "{var ", tname, "=");
TypeUtils.typeNameOrList(that, that.getTypeSpecifier().getType().getTypeModel(), this, false);
out(";", tname, ".$crtmm$=");
TypeUtils.encodeForRuntime(that, d, this, new RuntimeMetamodelAnnotationGenerator() {
@Override
public void generateAnnotations() {
TypeUtils.outputAnnotationsFunction(that.getAnnotationList(), d, GenerateJsVisitor.this);
}
});
out(";return ", tname, ";}");
endLine();
share(d);
}
use of org.eclipse.ceylon.model.typechecker.model.TypeAlias in project ceylon by eclipse.
the class TypeUtils method resolveTypeParameter.
/**
* Finds the owner of the type parameter and outputs a reference to the corresponding type argument.
*/
static void resolveTypeParameter(final Node node, final TypeParameter tp, final GenerateJsVisitor gen, final boolean skipSelfDecl) {
Scope parent = ModelUtil.getRealScope(node.getScope());
int outers = 0;
while (parent != null && parent != tp.getContainer()) {
if (parent instanceof TypeDeclaration && !(parent instanceof Constructor || ((TypeDeclaration) parent).isAnonymous())) {
outers++;
}
parent = parent.getScope();
}
if (tp.getContainer() instanceof ClassOrInterface) {
if (parent == tp.getContainer()) {
if (!skipSelfDecl) {
TypeDeclaration ontoy = ModelUtil.getContainingClassOrInterface(node.getScope());
while (ontoy.isAnonymous()) ontoy = ModelUtil.getContainingClassOrInterface(ontoy.getScope());
gen.out(gen.getNames().self(ontoy));
if (ontoy == parent)
outers--;
for (int i = 0; i < outers; i++) {
gen.out(".outer$");
}
gen.out(".");
}
gen.out("$$targs$$.", gen.getNames().typeParameterName(tp));
} else {
// This can happen in expressions such as Singleton(n) when n is dynamic
gen.out("{/*NO PARENT*/t:", gen.getClAlias(), "Anything}");
}
} else if (tp.getContainer() instanceof TypeAlias) {
if (parent == tp.getContainer()) {
gen.out("'", gen.getNames().typeParameterName(tp), "'");
} else {
// This can happen in expressions such as Singleton(n) when n is dynamic
gen.out("{/*NO PARENT ALIAS*/t:", gen.getClAlias(), "Anything}");
}
} else {
// it has to be a method, right?
// We need to find the index of the parameter where the argument occurs
// ...and it could be null...
Type type = null;
for (Iterator<ParameterList> iter0 = ((Function) tp.getContainer()).getParameterLists().iterator(); type == null && iter0.hasNext(); ) {
for (Iterator<Parameter> iter1 = iter0.next().getParameters().iterator(); iter1.hasNext(); ) {
type = typeContainsTypeParameter(iter1.next().getType(), tp);
}
}
// A type argument of the argument's type, in which case we must get the reified generic from the argument
if (tp.getContainer() == parent) {
gen.out(gen.getNames().typeArgsParamName((Function) tp.getContainer()), ".", gen.getNames().typeParameterName(tp));
} else {
if (parent == null && node instanceof Tree.StaticMemberOrTypeExpression) {
if (tp.getContainer() == ((Tree.StaticMemberOrTypeExpression) node).getDeclaration()) {
type = ((Tree.StaticMemberOrTypeExpression) node).getTarget().getTypeArguments().get(tp);
typeNameOrList(node, type, gen, skipSelfDecl);
return;
}
}
gen.out("'", gen.getNames().typeParameterName(tp), "'");
// gen.out.spitOut("Passing reference to " + tp.getQualifiedNameString() + " as a string...");
// gen.out("/*Please report this to the ceylon-js team: METHOD TYPEPARM plist ",
// Integer.toString(plistCount), "#", tp.getName(), "*/'", type.getProducedTypeQualifiedName(),
// "' container " + tp.getContainer() + " at " + node);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeAlias in project ceylon by eclipse.
the class Strategy method getEffectiveTypeParameters.
private static List<TypeParameter> getEffectiveTypeParameters(Declaration original, Declaration decl) {
if (Decl.isConstructor(original)) {
original = ModelUtil.getConstructedClass(original);
}
if (Decl.isConstructor(decl)) {
decl = ModelUtil.getConstructedClass(decl);
}
Scope container = decl.getContainer();
if (decl instanceof Value) {
if (decl.isStatic()) {
return getEffectiveTypeParameters(original, (Declaration) container);
} else {
return Collections.emptyList();
}
}
if (decl instanceof Function) {
if (original instanceof ClassAlias || decl.isStatic() && isCeylon(decl)) {
ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration) container));
copyDown.addAll(decl.getTypeParameters());
return copyDown;
} else {
return decl.getTypeParameters();
}
} else if (decl instanceof ClassAlias) {
// TODO
/*if (container instanceof Declaration) {
ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration)container));
copyDown.addAll(((Class)decl).getTypeParameters());
return copyDown;
} else*/
{
return ((ClassAlias) decl).getTypeParameters();
}
} else if (decl instanceof Class) {
if (((Class) decl).isStatic() && ((Class) decl).isMember() && isCeylon(decl)) {
// TODO and isCeylon
ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration) container));
copyDown.addAll(((Class) decl).getTypeParameters());
return copyDown;
} else {
return ((Class) decl).getTypeParameters();
}
} else if (decl instanceof Interface) {
/*if (((Interface) decl).isMember()) {
ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration)container));
copyDown.addAll(((Interface)decl).getTypeParameters());
return copyDown;
} else*/
{
return ((Interface) decl).getTypeParameters();
}
} else if (decl instanceof TypeAlias) {
return ((TypeAlias) decl).getTypeParameters();
} else {
throw BugException.unhandledDeclarationCase((Declaration) decl);
}
}
Aggregations