/** * Instructs the type checker that an unresolved variable is a dynamic variable. * @param returnType the type of the dynamic variable * Calling this method automatically sets the handled flag to true. * @param vexp the dynamic variable */ public void makeDynamic(VariableExpression vexp, ClassNode returnType) { context.getEnclosingMethod().putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, Boolean.TRUE); vexp.putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, returnType); storeType(vexp, returnType); setHandled(true); if (debug) { LOG.info("Turning '"+vexp.getText()+"' into a dynamic variable access of type "+returnType.toString(false)); } }
/** * Instructs the type checker that a property access is dynamic. * Calling this method automatically sets the handled flag to true. * @param pexp the property or attribute expression * @param returnType the type of the property */ public void makeDynamic(PropertyExpression pexp, ClassNode returnType) { context.getEnclosingMethod().putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, Boolean.TRUE); pexp.putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, returnType); storeType(pexp, returnType); setHandled(true); if (debug) { LOG.info("Turning '"+pexp.getText()+"' into a dynamic property access of type "+returnType.toString(false)); } }
@Override protected ClassNode createClosureClass(final ClosureExpression expression, final int mods) { ClassNode closureClass = super.createClosureClass(expression, mods); List<MethodNode> methods = closureClass.getDeclaredMethods("call"); List<MethodNode> doCall = closureClass.getMethods("doCall"); if (doCall.size() != 1) { throw new GroovyBugError("Expected to find one (1) doCall method on generated closure, but found " + doCall.size()); } MethodNode doCallMethod = doCall.get(0); if (methods.isEmpty() && doCallMethod.getParameters().length == 1) { createDirectCallMethod(closureClass, doCallMethod); } MethodTargetCompletionVisitor visitor = new MethodTargetCompletionVisitor(doCallMethod); Object dynamic = expression.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION); if (dynamic != null) { doCallMethod.putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, dynamic); } for (MethodNode method : methods) { visitor.visitMethod(method); } closureClass.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE, Boolean.TRUE); return closureClass; }
@Override public void visitMethod(final MethodNode node) { if (isSkipMode(node)) { node.putNodeMetaData(STATIC_COMPILE_NODE, false); } super.visitMethod(node); checkForConstructorWithCSButClassWithout(node); if (isStaticallyCompiled(node)) addDynamicOuterClassAccessorsCallback(node.getDeclaringClass()); }
node.putNodeMetaData(ERROR_COLLECTOR, collector);
/** * Used to instruct the type checker that the call is a dynamic method call. * Calling this method automatically sets the handled flag to true. * @param call the method call which is a dynamic method call * @param returnType the expected return type of the dynamic call * @return a virtual method node with the same name as the expected call */ public MethodNode makeDynamic(MethodCall call, ClassNode returnType) { TypeCheckingContext.EnclosingClosure enclosingClosure = context.getEnclosingClosure(); MethodNode enclosingMethod = context.getEnclosingMethod(); ((ASTNode)call).putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, returnType); if (enclosingClosure!=null) { enclosingClosure.getClosureExpression().putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, Boolean.TRUE); } else { enclosingMethod.putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, Boolean.TRUE); } setHandled(true); if (debug) { LOG.info("Turning "+call.getText()+" into a dynamic method call returning "+returnType.toString(false)); } return new MethodNode(call.getMethodAsString(), 0, returnType, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, EmptyStatement.INSTANCE); }
methodNode.putNodeMetaData(StaticTypeCheckingVisitor.class, Boolean.TRUE);
visitor.setCompilationUnit(compilationUnit); addTypeCheckingExtensions(visitor, extensions); methodNode.putNodeMetaData(STATIC_COMPILE_NODE, !visitor.isSkipMode(node)); if (declaringClass.getNodeMetaData(WriterControllerFactory.class) == null) { declaringClass.putNodeMetaData(WriterControllerFactory.class, factory);
newMethod.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, true);
); staticGetPropMethod.setSynthetic(true); staticGetPropMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,true); cn.addMethod(staticGetPropMethod); ); staticGetMissingMethod.setSynthetic(true); staticGetMissingMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,true); cn.addMethod(staticGetMissingMethod); if(!(cn instanceof InnerClassNode) || cn.isStaticClass()){ ); getMissingMethod.setSynthetic(true); getMissingMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,true); cn.addMethod(getMissingMethod); ); instanceGetMethod.setSynthetic(true); instanceGetMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,true); cn.addMethod(instanceGetMethod); ); setMethod.setSynthetic(true); setMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,true); cn.addMethod(setMethod); if(cn!=scriptClassNode){ ); getMethod.setSynthetic(true);
); staticGetPropMethod.setSynthetic(true); staticGetPropMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,true); cn.addMethod(staticGetPropMethod); ); staticGetMissingMethod.setSynthetic(true); staticGetMissingMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,true); cn.addMethod(staticGetMissingMethod); if(!(cn instanceof InnerClassNode) || cn.isStaticClass()){ ); getMissingMethod.setSynthetic(true); getMissingMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,true); cn.addMethod(getMissingMethod); ); instanceGetMethod.setSynthetic(true); instanceGetMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,true); cn.addMethod(instanceGetMethod); ); setMethod.setSynthetic(true); setMethod.putNodeMetaData(StaticCompilationMetadataKeys.STATIC_COMPILE_NODE,true); cn.addMethod(setMethod); if(cn!=scriptClassNode){ ); getMethod.setSynthetic(true);