use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.
the class Attr method checkMethod.
/**
* Check that method arguments conform to its instantiation.
*/
public Type checkMethod(Type site, final Symbol sym, ResultInfo resultInfo, Env<AttrContext> env, final List<JCExpression> argtrees, List<Type> argtypes, List<Type> typeargtypes) {
// an unchecked warning if its argument types change under erasure.
if (allowGenerics && (sym.flags() & STATIC) == 0 && (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
Type s = types.asOuterSuper(site, sym.owner);
if (s != null && s.isRaw() && !types.isSameTypes(sym.type.getParameterTypes(), sym.erasure(types).getParameterTypes())) {
chk.warnUnchecked(env.tree.pos(), "unchecked.call.mbr.of.raw.type", sym, s);
}
}
if (env.info.defaultSuperCallSite != null) {
for (Type sup : types.interfaces(env.enclClass.type).prepend(types.supertype((env.enclClass.type)))) {
if (!sup.tsym.isSubClass(sym.enclClass(), types) || types.isSameType(sup, env.info.defaultSuperCallSite))
continue;
List<MethodSymbol> icand_sup = types.interfaceCandidates(sup, (MethodSymbol) sym);
if (icand_sup.nonEmpty() && icand_sup.head != sym && icand_sup.head.overrides(sym, icand_sup.head.enclClass(), types, true)) {
log.error(env.tree.pos(), "illegal.default.super.call", env.info.defaultSuperCallSite, diags.fragment("overridden.default", sym, sup));
break;
}
}
env.info.defaultSuperCallSite = null;
}
if (sym.isStatic() && site.isInterface() && env.tree.hasTag(APPLY)) {
JCMethodInvocation app = (JCMethodInvocation) env.tree;
if (app.meth.hasTag(SELECT) && !TreeInfo.isStaticSelector(((JCFieldAccess) app.meth).selected, names)) {
log.error(env.tree.pos(), "illegal.static.intf.meth.call", site);
}
}
// Compute the identifier's instantiated type.
// For methods, we need to compute the instance type by
// Resolve.instantiate from the symbol's type as well as
// any type arguments and value arguments.
noteWarner.clear();
try {
Type owntype = rs.checkMethod(env, site, sym, resultInfo, argtypes, typeargtypes, noteWarner);
DeferredAttr.DeferredTypeMap checkDeferredMap = deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
argtypes = Type.map(argtypes, checkDeferredMap);
if (noteWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
chk.warnUnchecked(env.tree.pos(), "unchecked.meth.invocation.applied", kindName(sym), sym.name, rs.methodArguments(sym.type.getParameterTypes()), rs.methodArguments(Type.map(argtypes, checkDeferredMap)), kindName(sym.location()), sym.location());
// Don't erase the return type of the instantiated method type
// for Ceylon #1095
owntype = new MethodType(owntype.getParameterTypes(), sourceLanguage.isCeylon() && typeargtypes != null && !typeargtypes.isEmpty() ? owntype.getReturnType() : types.erasure(owntype.getReturnType()), types.erasure(owntype.getThrownTypes()), syms.methodClass);
}
return chk.checkMethod(owntype, sym, env, argtrees, argtypes, env.info.lastResolveVarargs(), resultInfo.checkContext.inferenceContext());
} catch (Infer.InferenceException ex) {
// invalid target type - propagate exception outwards or report error
// depending on the current check context
resultInfo.checkContext.report(env.tree.pos(), ex.getDiagnostic());
return types.createErrorType(site);
} catch (Resolve.InapplicableMethodException ex) {
final JCDiagnostic diag = ex.getDiagnostic();
Resolve.InapplicableSymbolError errSym = rs.new InapplicableSymbolError(null) {
@Override
protected Pair<Symbol, JCDiagnostic> errCandidate() {
return new Pair<Symbol, JCDiagnostic>(sym, diag);
}
};
List<Type> argtypes2 = Type.map(argtypes, rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, env.tree, sym, site, sym.name, argtypes2, typeargtypes);
log.report(errDiag);
return types.createErrorType(site);
}
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.
the class Attr method visitSelect.
/*
// Added by Ceylon
private Symbol resolveIndyCall(JCIndyIdent tree, List<Type> parameterTypes) {
return resolveIndyCall(tree, tree.indyReturnType, tree.indyParameterTypes, tree.name,
tree.bsmType, tree.bsmName, tree.bsmStatic,
parameterTypes);
}
*/
public void visitSelect(JCFieldAccess tree) {
// Determine the expected kind of the qualifier expression.
int skind = 0;
if (tree.name == names._this || tree.name == names._super || tree.name == names._class) {
skind = TYP;
} else {
if ((pkind() & PCK) != 0)
skind = skind | PCK;
if ((pkind() & TYP) != 0)
skind = skind | TYP | PCK;
if ((pkind() & (VAL | MTH)) != 0)
skind = skind | VAL | TYP;
}
// Attribute the qualifier expression, and determine its symbol (if any).
Type site = attribTree(tree.selected, env, new ResultInfo(skind, Infer.anyPoly));
if ((pkind() & (PCK | TYP)) == 0)
// Capture field access
site = capture(site);
// don't allow T.class T[].class, etc
if (skind == TYP) {
Type elt = site;
while (elt.hasTag(ARRAY)) elt = ((ArrayType) elt.unannotatedType()).elemtype;
if (elt.hasTag(TYPEVAR)) {
log.error(tree.pos(), "type.var.cant.be.deref");
result = tree.type = types.createErrorType(tree.name, site.tsym, site);
tree.sym = tree.type.tsym;
return;
}
}
// If qualifier symbol is a type or `super', assert `selectSuper'
// for the selection. This is relevant for determining whether
// protected symbols are accessible.
Symbol sitesym = TreeInfo.symbol(tree.selected);
boolean selectSuperPrev = env.info.selectSuper;
env.info.selectSuper = sitesym != null && sitesym.name == names._super;
// Determine the symbol represented by the selection.
env.info.pendingResolutionPhase = null;
Symbol sym = selectSym(tree, sitesym, site, env, resultInfo);
if (sym.kind == VAR && sym.name != names._super && env.info.defaultSuperCallSite != null) {
log.error(tree.selected.pos(), "not.encl.class", site.tsym);
sym = syms.errSymbol;
}
if (sym.exists() && !isType(sym) && (pkind() & (PCK | TYP)) != 0) {
site = capture(site);
sym = selectSym(tree, sitesym, site, env, resultInfo);
}
boolean varArgs = env.info.lastResolveVarargs();
tree.sym = sym;
if (site.hasTag(TYPEVAR) && !isType(sym) && sym.kind != ERR) {
while (site.hasTag(TYPEVAR)) site = site.getUpperBound();
site = capture(site);
}
// If that symbol is a variable, ...
if (sym.kind == VAR) {
VarSymbol v = (VarSymbol) sym;
// ..., evaluate its initializer, if it has one, and check for
// illegal forward reference.
checkInit(tree, env, v, true);
// that the variable is assignable in the current environment.
if (pkind() == VAR)
checkAssignable(tree.pos(), v, tree.selected, env);
}
if (sitesym != null && sitesym.kind == VAR && ((VarSymbol) sitesym).isResourceVariable() && sym.kind == MTH && sym.name.equals(names.close) && sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true) && env.info.lint.isEnabled(LintCategory.TRY)) {
log.warning(LintCategory.TRY, tree, "try.explicit.close.call");
}
// Disallow selecting a type from an expression
if (isType(sym) && (sitesym == null || (sitesym.kind & (TYP | PCK)) == 0)) {
tree.type = check(tree.selected, pt(), sitesym == null ? VAL : sitesym.kind, new ResultInfo(TYP | PCK, pt()));
}
if (isType(sitesym)) {
if (sym.name == names._this) {
// C.this' does not appear in a call to a super(...)
if (env.info.isSelfCall && site.tsym == env.enclClass.sym) {
chk.earlyRefError(tree.pos(), sym);
}
} else {
// Check if type-qualified fields or methods are static (JLS)
if ((sym.flags() & STATIC) == 0 && !env.next.tree.hasTag(REFERENCE) && sym.name != names._super && (sym.kind == VAR || sym.kind == MTH)) {
rs.accessBase(rs.new StaticError(sym), tree.pos(), site, sym.name, true);
}
}
if (!allowStaticInterfaceMethods && sitesym.isInterface() && sym.isStatic() && sym.kind == MTH) {
log.error(tree.pos(), sourceLanguage.isCeylon() ? "ceylon.static.interface.method.call" : "static.intf.method.invoke.not.supported.in.source", sourceName);
}
} else if (sym.kind != ERR && (sym.flags() & STATIC) != 0 && sym.name != names._class) {
// If the qualified item is not a type and the selected item is static, report
// a warning. Make allowance for the class of an array type e.g. Object[].class)
chk.warnStatic(tree, "static.not.qualified.by.type", Kinds.kindName(sym.kind), sym.owner);
}
// If we are selecting an instance member via a `super', ...
if (env.info.selectSuper && (sym.flags() & STATIC) == 0) {
// Check that super-qualified symbols are not abstract (JLS)
rs.checkNonAbstract(tree.pos(), sym);
if (site.isRaw()) {
// Determine argument types for site.
Type site1 = types.asSuper(env.enclClass.sym.type, site.tsym);
if (site1 != null)
site = site1;
}
}
if (env.info.isSerializable) {
chk.checkElemAccessFromSerializableLambda(tree);
}
// Ceylon: error if we try to select an interface static in < 1.8
/*if(sym != null
&& sym.isStatic()
&& (sym.kind & Kinds.MTH) != 0
&& sitesym != null
&& sitesym.isInterface()){
chk.checkStaticInterfaceMethodCall(tree);
}*/
env.info.selectSuper = selectSuperPrev;
result = checkId(tree, site, sym, env, resultInfo);
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.
the class LambdaToMethod method makeMetafactoryIndyCall.
/**
* Generate an indy method call to the meta factory
*/
private JCExpression makeMetafactoryIndyCall(LambdaAnalyzerPreprocessor.TranslationContext<?> context, int refKind, Symbol refSym, List<JCExpression> indy_args) {
JCFunctionalExpression tree = context.tree;
// determine the static bsm args
MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym);
List<Object> staticArgs = List.<Object>of(typeToMethodType(samSym.type), new Pool.MethodHandle(refKind, refSym, types), typeToMethodType(tree.getDescriptorType(types)));
// computed indy arg types
ListBuffer<Type> indy_args_types = new ListBuffer<>();
for (JCExpression arg : indy_args) {
indy_args_types.append(arg.type);
}
// finally, compute the type of the indy call
MethodType indyType = new MethodType(indy_args_types.toList(), tree.type, List.<Type>nil(), syms.methodClass);
Name metafactoryName = context.needsAltMetafactory() ? names.altMetafactory : names.metafactory;
if (context.needsAltMetafactory()) {
ListBuffer<Object> markers = new ListBuffer<>();
for (Type t : tree.targets.tail) {
if (t.tsym != syms.serializableType.tsym) {
markers.append(t.tsym);
}
}
int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0;
boolean hasMarkers = markers.nonEmpty();
boolean hasBridges = context.bridges.nonEmpty();
if (hasMarkers) {
flags |= FLAG_MARKERS;
}
if (hasBridges) {
flags |= FLAG_BRIDGES;
}
staticArgs = staticArgs.append(flags);
if (hasMarkers) {
staticArgs = staticArgs.append(markers.length());
staticArgs = staticArgs.appendList(markers.toList());
}
if (hasBridges) {
staticArgs = staticArgs.append(context.bridges.length() - 1);
for (Symbol s : context.bridges) {
Type s_erasure = s.erasure(types);
if (!types.isSameType(s_erasure, samSym.erasure(types))) {
staticArgs = staticArgs.append(s.erasure(types));
}
}
}
if (context.isSerializable()) {
int prevPos = make.pos;
try {
make.at(kInfo.clazz);
addDeserializationCase(refKind, refSym, tree.type, samSym, tree, staticArgs, indyType);
} finally {
make.at(prevPos);
}
}
}
return makeIndyCall(tree, syms.lambdaMetafactory, metafactoryName, staticArgs, indyType, indy_args, samSym.name);
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.
the class LambdaToMethod method deserTest.
private JCExpression deserTest(JCExpression prev, String func, String lit) {
MethodType eqmt = new MethodType(List.of(syms.objectType), syms.booleanType, List.<Type>nil(), syms.methodClass);
Symbol eqsym = rs.resolveQualifiedMethod(null, attrEnv, syms.objectType, names.equals, List.of(syms.objectType), List.<Type>nil());
JCMethodInvocation eqtest = make.Apply(List.<JCExpression>nil(), make.Select(deserGetter(func, syms.stringType), eqsym).setType(eqmt), List.<JCExpression>of(make.Literal(lit)));
eqtest.setType(syms.booleanType);
JCBinary compound = make.Binary(JCTree.Tag.AND, prev, eqtest);
compound.operator = rs.resolveBinaryOperator(null, JCTree.Tag.AND, attrEnv, syms.booleanType, syms.booleanType);
compound.setType(syms.booleanType);
return compound;
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.
the class LambdaToMethod method visitReference.
/**
* Translate a method reference into an invokedynamic call to the
* meta-factory.
* @param tree
*/
@Override
public void visitReference(JCMemberReference tree) {
LambdaAnalyzerPreprocessor.ReferenceTranslationContext localContext = (LambdaAnalyzerPreprocessor.ReferenceTranslationContext) context;
// first determine the method symbol to be used to generate the sam instance
// this is either the method reference symbol, or the bridged reference symbol
Symbol refSym = localContext.isSignaturePolymorphic() ? localContext.sigPolySym : tree.sym;
// the qualifying expression is treated as a special captured arg
JCExpression init;
switch(tree.kind) {
case IMPLICIT_INNER:
/**
* Inner :: new
*/
case SUPER:
/**
* super :: instMethod
*/
init = makeThis(localContext.owner.enclClass().asType(), localContext.owner.enclClass());
break;
case BOUND:
/**
* Expr :: instMethod
*/
init = tree.getQualifierExpression();
init = attr.makeNullCheck(init);
break;
case UNBOUND:
/**
* Type :: instMethod
*/
case STATIC:
/**
* Type :: staticMethod
*/
case TOPLEVEL:
/**
* Top level :: new
*/
case ARRAY_CTOR:
/**
* ArrayType :: new
*/
init = null;
break;
default:
throw new InternalError("Should not have an invalid kind");
}
List<JCExpression> indy_args = init == null ? List.<JCExpression>nil() : translate(List.of(init), localContext.prev);
// build a sam instance using an indy call to the meta-factory
result = makeMetafactoryIndyCall(localContext, localContext.referenceKind(), refSym, indy_args);
}
Aggregations