/** * Get method called from the bytecode interpreter, avoiding temporary stack creation. This method * is overwritten in JsArray and JsArguments. */ public void vmGetOperation(JsArray stack, int keyIndex, int valueIndex) { String key = stack.getString(keyIndex); Object old = getRawInPrototypeChain(key); if (old instanceof Integer) { stack.setObject(keyIndex, function.localNames[((Integer) old).intValue()]); context.vmGetOperation(stack, keyIndex, valueIndex); } else { super.vmGetOperation(stack, keyIndex, valueIndex); } }
static JsFunctionImpl create( JsParserResult parserResult, FunctionNode functionNode, List<Identifier> fqName, ModelBuilder modelBuilder, boolean isAnnonymous) { JsObjectImpl inObject = modelBuilder.getCurrentObject(); JsObject globalObject = modelBuilder.getGlobal(); JsObject parentObject = isAnnonymous ? globalObject : inObject; int start = Token.descPosition(functionNode.getFirstToken()); int end = Token.descPosition(functionNode.getLastToken()) + Token.descLength(functionNode.getLastToken()); List<Identifier> parameters = new ArrayList(functionNode.getParameters().size()); for (IdentNode node : functionNode.getParameters()) { parameters.add(create(parserResult, node)); } JsFunctionImpl result; if (fqName.size() > 1) { List<Identifier> objectName = fqName.subList(0, fqName.size() - 1); parentObject = isAnnonymous ? globalObject : ModelUtils.getJsObject(modelBuilder, objectName); result = new JsFunctionImpl( modelBuilder.getCurrentDeclarationScope(), parentObject, fqName.get(fqName.size() - 1), parameters, ModelUtils.documentOffsetRange(parserResult, start, end)); if (parentObject instanceof JsFunction && !"prototype".equals(parentObject.getName())) { result.addModifier(Modifier.STATIC); } } else { result = new JsFunctionImpl( modelBuilder.getCurrentDeclarationScope(), inObject, fqName.get(fqName.size() - 1), parameters, ModelUtils.documentOffsetRange(parserResult, start, end)); } String propertyName = result.getDeclarationName().getName(); JsObject property = parentObject.getProperty(propertyName); // the already existing property parentObject.addProperty(result.getDeclarationName().getName(), result); if (property != null) { result.addOccurrence(property.getDeclarationName().getOffsetRange()); for (Occurrence occurrence : property.getOccurrences()) { result.addOccurrence(occurrence.getOffsetRange()); } } JsDocumentationHolder docHolder = parserResult.getDocumentationHolder(); result.setDocumentation(docHolder.getDocumentation(functionNode)); result.setAnonymous(isAnnonymous); return result; }
static JsObjectImpl create( JsParserResult parserResult, ObjectNode objectNode, List<Identifier> fqName, ModelBuilder modelBuilder, boolean belongsToParent) { JsObjectImpl scope = modelBuilder.getCurrentObject(); JsObject parent = scope; JsObject result = null; Identifier name = fqName.get(fqName.size() - 1); JsObjectImpl newObject; if (!belongsToParent) { List<Identifier> objectName = fqName.size() > 1 ? fqName.subList(0, fqName.size() - 1) : fqName; parent = ModelUtils.getJsObject(modelBuilder, objectName); } result = parent.getProperty(name.getName()); newObject = new JsObjectImpl( parent, name, ModelUtils.documentOffsetRange( parserResult, objectNode.getStart(), objectNode.getFinish())); newObject.setDeclared(true); if (result != null) { // the object already exist due a definition of a property => needs to be copied for (String propertyName : result.getProperties().keySet()) { newObject.addProperty(propertyName, result.getProperty(propertyName)); } } JsDocumentationHolder docHolder = parserResult.getDocumentationHolder(); newObject.setDocumentation(docHolder.getDocumentation(objectNode)); parent.addProperty(name.getName(), newObject); return (JsObjectImpl) newObject; }