Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Xenos2017-03-27 21:47:10 +0000
committerStefan Xenos2017-03-31 22:41:23 +0000
commit2c42a0df455cbd5ba153f806bdbdfa9b2c3c7fd2 (patch)
treef47e3c44909cad1ccd2d70b55a127fc07ef67730
parentc0a948b58471feb266ae2a43da866986b3f3b1b4 (diff)
downloadeclipse.jdt.core-2c42a0df455cbd5ba153f806bdbdfa9b2c3c7fd2.tar.gz
eclipse.jdt.core-2c42a0df455cbd5ba153f806bdbdfa9b2c3c7fd2.tar.xz
eclipse.jdt.core-2c42a0df455cbd5ba153f806bdbdfa9b2c3c7fd2.zip
Bug 512741 - Indexer is performing too many writes during indexingI20170331-2000
Implement a new FieldList class and use it to replace several FieldOneToMany fields. Change-Id: I44e4d415453d77d034be2da7cff2c2318e0a878f
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/nd/FieldListTest.java320
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/nd/RunIndexTests.java1
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdNode.java26
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdStruct.java38
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdVisitor.java35
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/IndexExceptionBuilder.java3
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java2
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNode.java42
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNodeTypeRegistry.java6
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdStruct.java49
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/RawGrowableArray.java12
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/IndexException.java16
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/ModificationLog.java2
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/Field.java28
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldList.java327
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldManyToOne.java64
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldOneToMany.java17
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldOneToOne.java11
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/IField.java18
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/StructDef.java59
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/ClassFileToIndexConverter.java93
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java10
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/JavaIndex.java23
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotation.java26
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInConstant.java37
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInMethod.java39
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInMethodParameter.java39
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInType.java39
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInVariable.java39
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationValuePair.java22
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdBinding.java20
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdConstantAnnotation.java18
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethod.java51
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodAnnotationData.java30
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodException.java19
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodParameter.java29
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdResourceFile.java21
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdType.java52
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotation.java22
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInMethod.java39
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInType.java39
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInVariable.java39
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeBound.java17
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeParameter.java28
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdVariable.java38
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdZipEntry.java18
-rw-r--r--org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/util/MathUtils.java38
47 files changed, 1279 insertions, 682 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/nd/FieldListTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/nd/FieldListTest.java
new file mode 100644
index 0000000000..ad718cea77
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/nd/FieldListTest.java
@@ -0,0 +1,320 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Google, Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stefan Xenos (Google) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.nd;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.tests.nd.util.BaseTestCase;
+import org.eclipse.jdt.internal.core.nd.IDestructable;
+import org.eclipse.jdt.internal.core.nd.Nd;
+import org.eclipse.jdt.internal.core.nd.NdNode;
+import org.eclipse.jdt.internal.core.nd.NdNodeTypeRegistry;
+import org.eclipse.jdt.internal.core.nd.NdStruct;
+import org.eclipse.jdt.internal.core.nd.db.IString;
+import org.eclipse.jdt.internal.core.nd.field.FieldByte;
+import org.eclipse.jdt.internal.core.nd.field.FieldList;
+import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
+import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany;
+import org.eclipse.jdt.internal.core.nd.field.FieldString;
+import org.eclipse.jdt.internal.core.nd.field.StructDef;
+
+import junit.framework.Test;
+
+public class FieldListTest extends BaseTestCase {
+ static int nodeDeletions;
+ static int structDeletions;
+
+ public static class ElementNode extends NdNode {
+ public static final FieldString NAME;
+ public static final FieldOneToMany<TestStruct> RELATED_STRUCTS;
+ public static final FieldManyToOne<TestStruct> PARENT_NODE;
+ public static final FieldList<TestStruct> LIST_CONTENTS;
+
+ @SuppressWarnings("hiding")
+ public static final StructDef<ElementNode> type;
+
+ static {
+ type = StructDef.create(ElementNode.class, NdNode.type);
+
+ NAME = type.addString();
+ RELATED_STRUCTS = FieldOneToMany.create(type, TestStruct.RELATED_NODE);
+ PARENT_NODE = FieldManyToOne.createOwner(type, TestStruct.CHILD_NODES);
+ LIST_CONTENTS = FieldList.create(type, TestStruct.type, 3);
+ type.done();
+ }
+
+ public ElementNode(Nd nd, long record) {
+ super(nd, record);
+ }
+
+ public ElementNode(Nd nd, String name, TestStruct parent) {
+ super(nd);
+
+ NAME.put(nd, this.address, name);
+ PARENT_NODE.put(nd, this.address, parent);
+ }
+
+ public TestStruct createChild(String name) {
+ TestStruct result = LIST_CONTENTS.append(this.nd, this.address);
+ result.setName(name);
+ return result;
+ }
+
+ public List<TestStruct> getChildren() {
+ return LIST_CONTENTS.asList(getNd(), getAddress());
+ }
+
+ @Override
+ public void destruct() {
+ super.destruct();
+
+ FieldListTest.nodeDeletions++;
+ }
+
+ public IString getName() {
+ return NAME.get(getNd(), getAddress());
+ }
+
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ printStringTo(builder);
+ return builder.toString();
+ }
+
+ public void printStringTo(StringBuilder builder) {
+ builder.append(getName().getString());
+ if (!RELATED_STRUCTS.isEmpty(getNd(), getAddress())) {
+ builder.append("->[");
+ boolean isFirst = true;
+ for (TestStruct struct : getRelatedStructs()) {
+ if (!isFirst) {
+ builder.append(", ");
+ }
+ isFirst = false;
+ builder.append(struct.getName());
+ }
+ builder.append("]");
+ }
+
+ List<TestStruct> children = getChildren();
+ if (!children.isEmpty()) {
+ builder.append("(");
+ boolean isFirst = true;
+ for (TestStruct struct : children) {
+ if (!isFirst) {
+ builder.append(", ");
+ }
+ isFirst = false;
+ struct.printStringTo(builder);
+ }
+ builder.append(")");
+ }
+ }
+
+ public List<TestStruct> getRelatedStructs() {
+ return RELATED_STRUCTS.asList(getNd(), getAddress());
+ }
+ }
+
+ public static class TestStruct extends NdStruct implements IDestructable {
+ public static final FieldString NAME;
+ public static final FieldOneToMany<ElementNode> CHILD_NODES;
+ public static final FieldManyToOne<ElementNode> RELATED_NODE;
+ public static final FieldByte EXTRA_BYTE;
+
+ @SuppressWarnings("hiding")
+ public static final StructDef<TestStruct> type;
+
+ static {
+ type = StructDef.create(TestStruct.class, NdStruct.type);
+
+ NAME = type.addString();
+ CHILD_NODES = FieldOneToMany.create(type, ElementNode.PARENT_NODE);
+ RELATED_NODE = FieldManyToOne.create(type, ElementNode.RELATED_STRUCTS);
+ EXTRA_BYTE = type.addByte();
+ type.done();
+ }
+
+ public TestStruct(Nd nd, long record) {
+ super(nd, record);
+ }
+
+ public void printStringTo(StringBuilder builder) {
+ builder.append(getName().getString());
+ ElementNode related = RELATED_NODE.get(getNd(), getAddress());
+ if (related != null) {
+ builder.append("->[");
+ builder.append(related.getName().getString());
+ builder.append("]");
+ }
+
+ List<ElementNode> children = getChildren();
+ if (!children.isEmpty()) {
+ builder.append("(");
+ boolean isFirst = true;
+ for (ElementNode struct : children) {
+ if (!isFirst) {
+ builder.append(", ");
+ }
+ isFirst = false;
+ struct.printStringTo(builder);
+ }
+ builder.append(")");
+ }
+ }
+
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ printStringTo(builder);
+ return builder.toString();
+ }
+
+ public IString getName() {
+ return NAME.get(getNd(), getAddress());
+ }
+
+ public void setRelatedNode(ElementNode elementNode) {
+ RELATED_NODE.put(getNd(), getAddress(), elementNode);
+ }
+
+ public ElementNode getRelatedNode() {
+ return RELATED_NODE.get(getNd(), getAddress());
+ }
+
+ public void setName(String name) {
+ NAME.put(getNd(), getAddress(), name);
+ }
+
+ public List<ElementNode> getChildren() {
+ return CHILD_NODES.asList(getNd(), getAddress());
+ }
+
+ public ElementNode createChild(String name) {
+ return new ElementNode(getNd(), name, this);
+ }
+
+ @Override
+ public void destruct() {
+ FieldListTest.structDeletions++;
+ }
+ }
+
+ TestStruct referencer;
+ TestStruct owner;
+ private Nd nd;
+ private ElementNode root;
+ private boolean nodeDeleted;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ structDeletions = 0;
+ nodeDeletions = 0;
+ NdNodeTypeRegistry<NdNode> registry = new NdNodeTypeRegistry<>();
+ registry.register(0, ElementNode.type.getFactory());
+ this.nd = DatabaseTestUtil.createEmptyNd(getName(), registry);
+ this.nd.getDB().setExclusiveLock();
+ this.root = new ElementNode(this.nd, "root", null);
+ }
+
+ protected void freeAllMemory() throws Exception {
+ if (this.nodeDeleted) {
+ return;
+ }
+ this.nodeDeleted = true;
+ this.root.delete();
+ this.nd.processDeletions();
+ long freed = this.nd.getDB().getBytesFreed();
+ long allocated = this.nd.getDB().getBytesAllocated();
+ assertEquals("We should have freed all the bytes we allocated and no more", allocated, freed);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ freeAllMemory();
+ super.tearDown();
+ }
+
+ public void testEmptyList() throws Exception {
+ assertTrue("isEmpty() should return true if no children inserted",
+ this.root.getChildren().isEmpty());
+ freeAllMemory();
+ assertEquals("No structs should have been disposed during this test", 0, structDeletions);
+ assertEquals("One node should have been disposed during this test", 1, nodeDeletions);
+ }
+
+ public void testOneChild() throws Exception {
+ TestStruct testStruct = this.root.createChild("child");
+ assertEquals("root should be initialized properly", "child", testStruct.getName().getString());
+ assertEquals("root should have correct contents", "root(child)", this.root.toString());
+ freeAllMemory();
+ assertEquals("No structs should have been disposed during this test", 1, structDeletions);
+ assertEquals("One node should have been disposed during this test", 1, nodeDeletions);
+ }
+
+ public void testElementsInBlock() throws Exception {
+ this.root.createChild("child1");
+ this.root.createChild("child2");
+ assertEquals("root should have correct contents", "root(child1, child2)", this.root.toString());
+ this.root.createChild("child3");
+ assertEquals("root should have correct contents", "root(child1, child2, child3)",
+ this.root.toString());
+ this.root.createChild("child4");
+ assertEquals("root should have correct contents", "root(child1, child2, child3, child4)",
+ this.root.toString());
+ this.root.createChild("child5");
+ assertEquals("root should have correct contents", "root(child1, child2, child3, child4, child5)",
+ this.root.toString());
+ freeAllMemory();
+ assertEquals("No structs should have been disposed during this test", 5, structDeletions);
+ assertEquals("One node should have been disposed during this test", 1, nodeDeletions);
+ }
+
+ public void testDestructorInPartiallyFilledBlock() throws Exception {
+ this.root.createChild("child1");
+ this.root.createChild("child2");
+ this.root.createChild("child3");
+ this.root.createChild("child4");
+ freeAllMemory();
+ assertEquals("No structs should have been disposed during this test", 4, structDeletions);
+ assertEquals("One node should have been disposed during this test", 1, nodeDeletions);
+ }
+
+ public void testListOwningNode() throws Exception {
+ TestStruct child1 = this.root.createChild("child1");
+ child1.createChild("grandchild1");
+
+ assertEquals("root should have correct contents", "root(child1(grandchild1))", this.root.toString());
+
+ freeAllMemory();
+ assertEquals("No structs should have been disposed during this test", 1, structDeletions);
+ assertEquals("One node should have been disposed during this test", 2, nodeDeletions);
+ }
+
+ public void testListWithManyToOneNode() throws Exception {
+ TestStruct child1 = this.root.createChild("child1");
+ ElementNode relatedNode = new ElementNode(this.nd, "relatedNode", null);
+ child1.setRelatedNode(relatedNode);
+
+ assertEquals("Related node should have been set", relatedNode, child1.getRelatedNode());
+ assertEquals("root should have correct contents", "root(child1->[relatedNode])", this.root.toString());
+
+ this.root.delete();
+ this.nodeDeleted = true;
+
+ assertEquals("Related node should be cleared", null, child1.getRelatedNode());
+ }
+
+ public static Test suite() {
+ return BaseTestCase.suite(FieldListTest.class);
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/nd/RunIndexTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/nd/RunIndexTests.java
index f358ea0bb9..9bb4a9fb12 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/nd/RunIndexTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/nd/RunIndexTests.java
@@ -30,6 +30,7 @@ public static Class[] getAllTestClasses() {
ChunkWriterTests.class,
DatabaseTest.class,
FieldBackPointerTest.class,
+ FieldListTest.class,
FieldOneToOneTest.class,
IndexerTest.class,
InheritenceTests.class,
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdNode.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdNode.java
deleted file mode 100644
index ef24eb6fbe..0000000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdNode.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2015, 2016 Google, Inc and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.nd;
-
-import org.eclipse.jdt.internal.core.nd.db.IndexException;
-
-/**
- * Interface for all nodes that can be visited by a {@link INdVisitor}.
- * @noextend This interface is not intended to be extended by clients.
- * @noimplement This interface is not intended to be implemented by clients.
- */
-public interface INdNode {
-
- /**
- * Visits the children of this node.
- */
- public void accept(INdVisitor visitor) throws IndexException;
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdStruct.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdStruct.java
new file mode 100644
index 0000000000..909fd562ce
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdStruct.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Google, Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stefan Xenos (Google) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.nd;
+
+/**
+ * Implementations of this interface wrap content in the database as a java object.
+ * All such objects have an address and a pointer to the database.
+ */
+public interface INdStruct {
+ /**
+ * Returns the database address at which the struct begins.
+ */
+ public long getAddress();
+
+ /**
+ * Returns the database backing this struct.
+ */
+ public Nd getNd();
+
+ /**
+ * Given a nullable {@link INdStruct}, this returns the address of the struct
+ * or 0 if the object was null.
+ */
+ static long addressOf(INdStruct nullable) {
+ if (nullable == null) {
+ return 0;
+ }
+ return nullable.getAddress();
+ }
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdVisitor.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdVisitor.java
deleted file mode 100644
index 034e233021..0000000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/INdVisitor.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2015, 2016 Google, Inc and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.nd;
-
-import org.eclipse.core.runtime.CoreException;
-
-public interface INdVisitor {
-
- /**
- * Walk the nodes in a {@link Nd}. Return true to visit the children of
- * this node, or false to skip to the next sibling of this node.
- * Throw CoreException to stop the visit.
- *
- * @param node being visited
- * @return whether to visit children
- */
- public boolean visit(INdNode node) throws CoreException;
-
- /**
- * All children have been visited, about to go back to the parent.
- *
- * @param node that has just completed visitation
- * @throws CoreException
- */
- public void leave(INdNode node) throws CoreException;
-
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/IndexExceptionBuilder.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/IndexExceptionBuilder.java
index 42d9b5a491..7994234d9a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/IndexExceptionBuilder.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/IndexExceptionBuilder.java
@@ -72,6 +72,9 @@ public final class IndexExceptionBuilder {
*/
public IndexException build(String description) {
IndexException toThrow = new IndexException(description);
+ if (this.db.getLog().enabled()) {
+ toThrow.setTime(this.db.getLog().getWriteCount());
+ }
attachTo(toThrow);
return toThrow;
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java
index 9b20c451c0..a8acff19f7 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/Nd.java
@@ -650,7 +650,7 @@ public final class Nd {
/**
* Returns the type ID for the given class
*/
- public short getNodeType(Class<? extends NdNode> toQuery) {
+ public short getNodeType(Class<?> toQuery) {
return this.fNodeTypeRegistry.getTypeForClass(toQuery);
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNode.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNode.java
index d550751e3c..ddf646e6ed 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNode.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNode.java
@@ -16,29 +16,22 @@ import org.eclipse.jdt.internal.core.nd.field.FieldShort;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
/**
- * This is a basic node in the network database.
+ * This is a basic polymorphic node in the network database. Pointers to NdNode or any of their
+ * subclasses will be resolved to the correct subclass of NdNode such that the correct version of an
+ * overloaded method will be invoked.
*/
-public abstract class NdNode implements IDestructable {
+public abstract class NdNode extends NdStruct implements IDestructable {
public static final FieldShort NODE_TYPE;
+ @SuppressWarnings("hiding")
public static final StructDef<NdNode> type;
static {
- type = StructDef.create(NdNode.class);
+ type = StructDef.create(NdNode.class, NdStruct.type);
NODE_TYPE = type.addShort();
type.done();
}
- public final long address;
- private Nd nd;
-
- public static long addressOf(NdNode nullable) {
- if (nullable == null) {
- return 0;
- }
- return nullable.address;
- }
-
/**
* Load a node from the specified address in the given database. Return null if a node cannot
* be loaded.
@@ -63,7 +56,7 @@ public abstract class NdNode implements IDestructable {
}
@SuppressWarnings("unchecked")
- public static <T extends NdNode> T load(Nd nd, long address, StructDef<T> targetType) {
+ public static <T extends INdStruct> T load(Nd nd, long address, StructDef<T> typeToLoad) {
if (address == 0) {
return null;
}
@@ -78,7 +71,7 @@ public abstract class NdNode implements IDestructable {
throw e;
}
- Class<T> clazz = targetType.getStructClass();
+ Class<T> clazz = typeToLoad.getStructClass();
if (!clazz.isAssignableFrom(result.getClass())) {
throw nd.describeProblem()
.addProblemAddress(NODE_TYPE, address)
@@ -86,7 +79,7 @@ public abstract class NdNode implements IDestructable {
clazz + " but found " + result.getClass()); //$NON-NLS-1$
}
- return (T)result;
+ return (T) result;
}
/**
@@ -97,13 +90,12 @@ public abstract class NdNode implements IDestructable {
}
protected NdNode(Nd nd, long address) {
- this.nd = nd;
- this.address = address;
+ super(nd, address);
}
protected NdNode(Nd nd) {
+ super(nd, 0);
Database db = nd.getDB();
- this.nd = nd;
short nodeType = nd.getNodeType(getClass());
ITypeFactory<? extends NdNode> factory1 = nd.getTypeFactory(nodeType);
@@ -113,14 +105,6 @@ public abstract class NdNode implements IDestructable {
NODE_TYPE.put(nd, this.address, nodeType);
}
- protected Database getDB() {
- return this.nd.getDB();
- }
-
- public final Nd getNd() {
- return this.nd;
- }
-
/**
* Return a value to uniquely identify the node within the factory that is responsible for loading
* instances of this node from the {@link Nd}.
@@ -155,10 +139,6 @@ public abstract class NdNode implements IDestructable {
return (int) (this.address >> Database.BLOCK_SIZE_DELTA_BITS);
}
- public void accept(INdVisitor visitor) {
- // No children here.
- }
-
/**
* Return an value to globally identify the given node within the given linkage. This value
* can be used for comparison with other {@link NdNode}s.
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNodeTypeRegistry.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNodeTypeRegistry.java
index d15b7790b8..12c2fd72e8 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNodeTypeRegistry.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdNodeTypeRegistry.java
@@ -75,7 +75,11 @@ public class NdNodeTypeRegistry<R> {
return typeFactory.create(nd, address);
}
- public short getTypeForClass(Class<? extends R> toQuery) {
+ public boolean isRegisteredClass(Class<?> toQuery) {
+ return this.registeredClasses.containsKey(toQuery);
+ }
+
+ public short getTypeForClass(Class<?> toQuery) {
Short classId = this.registeredClasses.get(toQuery);
if (classId == null) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdStruct.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdStruct.java
new file mode 100644
index 0000000000..5bdec2ab78
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/NdStruct.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Google, Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stefan Xenos (Google) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.nd;
+
+import org.eclipse.jdt.internal.core.nd.db.Database;
+import org.eclipse.jdt.internal.core.nd.field.StructDef;
+
+/**
+ * Base class for standard implementations of {@link INdStruct}. Holds the address of the struct
+ * and the pointer to the database.
+ */
+public class NdStruct implements INdStruct {
+ public long address;
+ protected final Nd nd;
+
+ public static final StructDef<NdStruct> type;
+
+ static {
+ type = StructDef.createAbstract(NdStruct.class);
+ type.done();
+ }
+
+ protected NdStruct(Nd nd, long address) {
+ this.nd = nd;
+ this.address = address;
+ }
+
+ @Override
+ public long getAddress() {
+ return this.address;
+ }
+
+ @Override
+ public Nd getNd() {
+ return this.nd;
+ }
+
+ protected final Database getDB() {
+ return this.nd.getDB();
+ }
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/RawGrowableArray.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/RawGrowableArray.java
index ac3ede103e..67117526e7 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/RawGrowableArray.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/RawGrowableArray.java
@@ -16,6 +16,7 @@ import org.eclipse.jdt.internal.core.nd.field.FieldInt;
import org.eclipse.jdt.internal.core.nd.field.FieldPointer;
import org.eclipse.jdt.internal.core.nd.field.FieldShort;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
+import org.eclipse.jdt.internal.core.nd.util.MathUtils;
/**
* Implements a growable array of pointers that supports constant-time insertions and removals. Items are inserted at
@@ -585,7 +586,7 @@ public final class RawGrowableArray {
// For sizes larger than the max block size, we need to use a metablock. In this case, the allocated size
// will be a multiple of the max block size.
- return roundUpToMultipleOf(GrowableBlockHeader.MAX_GROWABLE_SIZE, growableRegionSize);
+ return MathUtils.roundUpToNearestMultiple(growableRegionSize, GrowableBlockHeader.MAX_GROWABLE_SIZE);
}
return nextGrowableSize;
@@ -618,15 +619,6 @@ public final class RawGrowableArray {
}
/**
- * Rounds a value up to the nearest multiple of another value
- */
- private static int roundUpToMultipleOf(int unit, int valueToRound) {
- int numberOfMetablocks = (valueToRound + unit - 1) / unit;
-
- return numberOfMetablocks * unit;
- }
-
- /**
* Returns the record size for a RawGrowableSize with the given number of inline records
*/
public int getRecordSize() {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/IndexException.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/IndexException.java
index aa195b8b93..f971fb8db4 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/IndexException.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/IndexException.java
@@ -23,6 +23,7 @@ public class IndexException extends RuntimeException {
private IStatus status;
private List<RelatedAddress> relatedAddresses = new ArrayList<>();
+ private long time = -1;
public IndexException(IStatus status) {
this.status = status;
@@ -32,6 +33,16 @@ public class IndexException extends RuntimeException {
this(new Status(IStatus.ERROR, "org.eclipse.jdt.core", message)); //$NON-NLS-1$
}
+ /**
+ * Sets the time that the exception occurred at (in terms of the write number
+ * from the modification log)
+ *
+ * @param writeNumber
+ */
+ public void setTime(long writeNumber) {
+ this.time = writeNumber;
+ }
+
@Override
public synchronized Throwable getCause() {
return this.status.getException();
@@ -59,6 +70,11 @@ public class IndexException extends RuntimeException {
@Override
public String getMessage() {
StringBuilder result = new StringBuilder();
+ if (this.time != -1) {
+ result.append("(time "); //$NON-NLS-1$
+ result.append(this.time);
+ result.append(") "); //$NON-NLS-1$
+ }
result.append(this.status.getMessage());
if (!this.relatedAddresses.isEmpty()) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/ModificationLog.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/ModificationLog.java
index 1229343ecb..b81b37fa83 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/ModificationLog.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/db/ModificationLog.java
@@ -311,7 +311,7 @@ public class ModificationLog {
}
}
- private boolean enabled() {
+ public boolean enabled() {
return this.buffer0 != null;
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/Field.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/Field.java
index efd6e8eb0f..f596d883de 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/Field.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/Field.java
@@ -12,6 +12,7 @@ package org.eclipse.jdt.internal.core.nd.field;
import org.eclipse.jdt.internal.core.nd.ITypeFactory;
import org.eclipse.jdt.internal.core.nd.Nd;
+import org.eclipse.jdt.internal.core.nd.db.Database;
/**
* Used to represent a single field of an object stored in the database. Objects
@@ -54,4 +55,31 @@ public final class Field<T> extends BaseField implements IDestructableField {
public int getRecordSize() {
return this.factory.getRecordSize();
}
+
+ @Override
+ public int getAlignment() {
+ // This sort of field is almost always used for embedding NdStructs within
+ // other data types. Since most NdStructs allow incoming record pointers, they need to
+ // be properly aligned. If we ever want to use this sort of field for other data types
+ // that don't require alignment, we may want to replace this with something smarter
+ // that can figure out the correct alignment based on the requirements of the actual
+ // data type.
+ return Database.BLOCK_SIZE_DELTA;
+ }
+
+ /**
+ * Creates a new {@link Field} in the given struct with the given type.
+ *
+ * @param struct the struct that will contain the newly-created field (must not have had
+ * {@link StructDef#done()} called on it yet).
+ * @param fieldType the data type for the contents of the newly created field
+ * @return the newly-constructed field
+ */
+ public static <T> Field<T> create(StructDef<?> struct, StructDef<T> fieldType) {
+ Field<T> result = new Field<>(fieldType.getFactory(), struct.getStructName(), struct.getNumFields());
+ struct.add(result);
+ struct.addDestructableField(result);
+ fieldType.addDependency(struct);
+ return result;
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldList.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldList.java
new file mode 100644
index 0000000000..b2c5ec70a6
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldList.java
@@ -0,0 +1,327 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Google, Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stefan Xenos (Google) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.nd.field;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.internal.core.nd.ITypeFactory;
+import org.eclipse.jdt.internal.core.nd.Nd;
+import org.eclipse.jdt.internal.core.nd.db.Database;
+import org.eclipse.jdt.internal.core.nd.db.ModificationLog;
+import org.eclipse.jdt.internal.core.nd.db.ModificationLog.Tag;
+import org.eclipse.jdt.internal.core.nd.util.MathUtils;
+
+/**
+ * Stores a singly-linked list of blocks, each of which contains a variable number of embedded elements.
+ * Each block contains a header containing the size of the block and pointer to the next block, followed
+ * by the embedded elements themselves.
+ */
+public class FieldList<T> extends BaseField implements IDestructableField {
+ /**
+ * Pointer to the first block.
+ */
+ public final static FieldPointer FIRST_BLOCK;
+ /**
+ * Pointer to the block where insertions are currently happening. This is only null if there are no allocated
+ * blocks. If there are any blocks containing elements, this points to the last block with a nonzero number of
+ * elements.
+ */
+ public final static FieldPointer LAST_BLOCK_WITH_ELEMENTS;
+
+ @SuppressWarnings("rawtypes")
+ private static final StructDef<FieldList> type;
+ private static final int LIST_HEADER_BYTES;
+ private static final long MAX_BYTES_IN_A_CHUNK = Database.getBytesThatFitInChunks(1);
+
+ private final StructDef<T> elementType;
+ private final int elementsPerBlock;
+ private final StructDef<?> ownerType;
+ private final Tag allocateTag;
+ private final Tag appendTag;
+ private final Tag destructTag;
+
+ static {
+ type = StructDef.createAbstract(FieldList.class);
+ FIRST_BLOCK = type.addPointer();
+ LAST_BLOCK_WITH_ELEMENTS = type.addPointer();
+
+ type.done();
+ LIST_HEADER_BYTES = MathUtils.roundUpToNearestMultipleOfPowerOfTwo(type.size(), Database.BLOCK_SIZE_DELTA);
+ }
+
+ private static class BlockHeader {
+ // This points to the next block if there is one, or null if not.
+ public final static FieldPointer NEXT_BLOCK;
+ public final static FieldShort BLOCK_SIZE;
+ public final static FieldShort ELEMENTS_IN_USE;
+ public static final int BLOCK_HEADER_BYTES;
+
+ @SuppressWarnings("hiding")
+ private static final StructDef<BlockHeader> type;
+
+ static {
+ type = StructDef.createAbstract(BlockHeader.class);
+
+ NEXT_BLOCK = type.addPointer();
+ BLOCK_SIZE = type.addShort();
+ ELEMENTS_IN_USE = type.addShort();
+ type.done();
+
+ BLOCK_HEADER_BYTES = MathUtils.roundUpToNearestMultipleOfPowerOfTwo(type.size(), Database.BLOCK_SIZE_DELTA);
+ }
+ }
+
+ private FieldList(StructDef<?> ownerType, StructDef<T> elementType, int elementsPerBlock) {
+ this.elementType = elementType;
+ this.elementsPerBlock = elementsPerBlock;
+ this.ownerType = ownerType;
+ int fieldNumber = ownerType.getNumFields();
+ setFieldName("field " + fieldNumber + ", a " + getClass().getSimpleName() //$NON-NLS-1$//$NON-NLS-2$
+ + " in struct " + ownerType.getStructName());//$NON-NLS-1$
+ this.allocateTag = ModificationLog.createTag("Allocating elements for " + getFieldName()); //$NON-NLS-1$
+ this.appendTag = ModificationLog.createTag("Appending to " + getFieldName()); //$NON-NLS-1$
+ this.destructTag = ModificationLog.createTag("Deallocating " + getFieldName()); //$NON-NLS-1$
+ }
+
+ /**
+ * Creates a new {@link FieldList} in the given struct which contains elements of the given type. The resulting list
+ * will grow by 1 element each time it overflows.
+ *
+ * @param ownerStruct
+ * the struct to which the new list field will be added. Must not have had {@link StructDef#done()}
+ * invoked on it yet.
+ * @param elementType
+ * the type of elements that will be contained in the struct.
+ * @return a newly-constructed list field in the given struct.
+ */
+ public static <T> FieldList<T> create(StructDef<?> ownerStruct, StructDef<T> elementType) {
+ return create(ownerStruct, elementType, 1);
+ }
+
+ /**
+ * Creates a new {@link FieldList} in the given struct which contains elements of the given type. The resulting list
+ * will grow by the given number of elements each time it overflows.
+ *
+ * @param ownerStruct
+ * the struct to which the new list field will be added. Must not have had {@link StructDef#done()}
+ * invoked on it yet.
+ * @param elementType
+ * the type of elements that will be contained in the struct.
+ * @param elementsPerBlock
+ * the number of elements that will be allocated each time the list overflows.
+ * @return a newly-constructed list field in the given struct.
+ */
+ public static <T> FieldList<T> create(StructDef<?> ownerStruct, StructDef<T> elementType, int elementsPerBlock) {
+ FieldList<T> result = new FieldList<>(ownerStruct, elementType, elementsPerBlock);
+ ownerStruct.add(result);
+ ownerStruct.addDestructableField(result);
+ return result;
+ }
+
+ private int getElementSize() {
+ int recordSize = this.elementType.getFactory().getRecordSize();
+ return MathUtils.roundUpToNearestMultipleOfPowerOfTwo(recordSize, Database.BLOCK_SIZE_DELTA);
+ }
+
+ @Override
+ public int getRecordSize() {
+ return LIST_HEADER_BYTES;
+ }
+
+ /**
+ * Returns the contents of the receiver as a {@link List}.
+ *
+ * @param nd the database to be queried.
+ * @param address the address of the parent struct
+ */
+ public List<T> asList(Nd nd, long address) {
+ long headerStartAddress = address + this.offset;
+ long firstBlockAddress = FIRST_BLOCK.get(nd, headerStartAddress);
+
+ List<T> result = new ArrayList<>();
+
+ long nextBlockAddress = firstBlockAddress;
+ while (nextBlockAddress != 0) {
+ long currentBlockAddress = nextBlockAddress;
+ nextBlockAddress = BlockHeader.NEXT_BLOCK.get(nd, currentBlockAddress);
+ int elementsInBlock = BlockHeader.ELEMENTS_IN_USE.get(nd, currentBlockAddress);
+ long firstElementInBlockAddress = currentBlockAddress + BlockHeader.BLOCK_HEADER_BYTES;
+
+ readElements(result, nd, firstElementInBlockAddress, elementsInBlock);
+ }
+
+ return result;
+ }
+
+ private void readElements(List<T> result, Nd nd, long nextElementAddress, int count) {
+ ITypeFactory<T> factory = this.elementType.getFactory();
+
+ int size = getElementSize();
+ for (; count > 0; count--) {
+ result.add(factory.create(nd, nextElementAddress));
+ nextElementAddress += size;
+ }
+ }
+
+ public T append(Nd nd, long address) {
+ Database db = nd.getDB();
+ db.getLog().start(this.appendTag);
+ try {
+ long headerStartAddress = address + this.offset;
+ long nextBlockAddress = LAST_BLOCK_WITH_ELEMENTS.get(nd, headerStartAddress);
+
+ // Ensure that there's at least one block
+ long insertionBlockAddress = nextBlockAddress;
+ if (nextBlockAddress == 0) {
+ long newBlockAddress = allocateNewBlock(nd, this.elementsPerBlock);
+ LAST_BLOCK_WITH_ELEMENTS.put(nd, headerStartAddress, newBlockAddress);
+ FIRST_BLOCK.put(nd, headerStartAddress, newBlockAddress);
+ insertionBlockAddress = newBlockAddress;
+ }
+
+ // Check if there's any free space in this block
+ int elementsInBlock = BlockHeader.ELEMENTS_IN_USE.get(nd, insertionBlockAddress);
+ int blockSize = BlockHeader.BLOCK_SIZE.get(nd, insertionBlockAddress);
+
+ if (elementsInBlock >= blockSize) {
+ long nextBlock = BlockHeader.NEXT_BLOCK.get(nd, insertionBlockAddress);
+ if (nextBlock == 0) {
+ nextBlock = allocateNewBlock(nd, this.elementsPerBlock);
+ BlockHeader.NEXT_BLOCK.put(nd, insertionBlockAddress, nextBlock);
+ }
+ LAST_BLOCK_WITH_ELEMENTS.put(nd, headerStartAddress, nextBlock);
+ insertionBlockAddress = nextBlock;
+ elementsInBlock = BlockHeader.ELEMENTS_IN_USE.get(nd, insertionBlockAddress);
+ }
+
+ BlockHeader.ELEMENTS_IN_USE.put(nd, insertionBlockAddress, (short) (elementsInBlock + 1));
+ int elementSize = getElementSize();
+
+ long resultAddress = insertionBlockAddress + BlockHeader.BLOCK_HEADER_BYTES + elementsInBlock * elementSize;
+ assert ((resultAddress - Database.BLOCK_HEADER_SIZE) & (Database.BLOCK_SIZE_DELTA - 1)) == 0;
+ return this.elementType.getFactory().create(nd, resultAddress);
+ } finally {
+ db.getLog().end(this.appendTag);
+ }
+ }
+
+ /**
+ * Ensures that the receiver will have space for the given number of elements without additional
+ * allocation. Callers should invoke this prior to a sequence of {@link FieldList#append(Nd, long)}
+ * calls if they know in advance how many elements will be appended. Will create the minimum number
+ * of extra blocks needed to the given number of additional elements.
+ */
+ public void allocate(Nd nd, long address, int numElements) {
+ Database db = nd.getDB();
+ db.getLog().start(this.allocateTag);
+ try {
+ if (numElements == 0) {
+ // Not an error, but there's nothing to do if the caller didn't actually ask for anything to be allocated.
+ return;
+ }
+ long headerStartAddress = address + this.offset;
+ long nextBlockAddress = LAST_BLOCK_WITH_ELEMENTS.get(nd, headerStartAddress);
+
+ int maxBlockSizeThatFitsInAChunk = (int) ((MAX_BYTES_IN_A_CHUNK - BlockHeader.BLOCK_HEADER_BYTES)
+ / getElementSize());
+
+ // Ensure that there's at least one block
+ if (nextBlockAddress == 0) {
+ int firstAllocation = Math.min(numElements, maxBlockSizeThatFitsInAChunk);
+ nextBlockAddress = allocateNewBlock(nd, firstAllocation);
+ LAST_BLOCK_WITH_ELEMENTS.put(nd, headerStartAddress, nextBlockAddress);
+ FIRST_BLOCK.put(nd, headerStartAddress, nextBlockAddress);
+ }
+
+ // Check if there's any free space in this block
+ int remainingToAllocate = numElements;
+ while (true) {
+ long currentBlockAddress = nextBlockAddress;
+ nextBlockAddress = BlockHeader.NEXT_BLOCK.get(nd, currentBlockAddress);
+ int elementsInUse = BlockHeader.ELEMENTS_IN_USE.get(nd, currentBlockAddress);
+ int blockSize = BlockHeader.BLOCK_SIZE.get(nd, currentBlockAddress);
+
+ remainingToAllocate -= (blockSize - elementsInUse);
+ if (remainingToAllocate <= 0) {
+ break;
+ }
+
+ if (nextBlockAddress == 0) {
+ nextBlockAddress = allocateNewBlock(nd, Math.min(maxBlockSizeThatFitsInAChunk, numElements));
+ BlockHeader.NEXT_BLOCK.put(nd, currentBlockAddress, nextBlockAddress);
+ }
+ }
+ } finally {
+ db.getLog().end(this.allocateTag);
+ }
+ }
+
+ private long allocateNewBlock(Nd nd, int blockSize) {
+ short poolId = getMemoryPoolId(nd);
+ int elementSize = getElementSize();
+ long bytesNeeded = BlockHeader.BLOCK_HEADER_BYTES + blockSize * elementSize;
+ // If we're close enough to filling the chunk that we wouldn't be able to fit any more elements anyway, allocate
+ // the entire chunk. Although it wastes a small amount of space, it ensures that the blocks can be more easily
+ // reused rather than being fragmented. It also allows freed blocks to be merged via the large block allocator.
+ if (MAX_BYTES_IN_A_CHUNK - bytesNeeded < elementSize) {
+ bytesNeeded = MAX_BYTES_IN_A_CHUNK;
+ }
+ long result = nd.getDB().malloc(bytesNeeded, poolId);
+ BlockHeader.BLOCK_SIZE.put(nd, result, (short) blockSize);
+ return result;
+ }
+
+ private short getMemoryPoolId(Nd nd) {
+ short poolId = Database.POOL_LINKED_LIST;
+ if (this.ownerType != null) {
+ Class<?> structClass = this.ownerType.getStructClass();
+ if (nd.getTypeRegistry().isRegisteredClass(structClass)) {
+ poolId = (short) (Database.POOL_FIRST_NODE_TYPE + nd.getNodeType(structClass));
+ }
+ }
+ return poolId;
+ }
+
+ @Override
+ public void destruct(Nd nd, long address) {
+ Database db = nd.getDB();
+ db.getLog().start(this.destructTag);
+ try {
+ short poolId = getMemoryPoolId(nd);
+ long headerStartAddress = address + this.offset;
+ long firstBlockAddress = FIRST_BLOCK.get(nd, headerStartAddress);
+
+ long nextBlockAddress = firstBlockAddress;
+ while (nextBlockAddress != 0) {
+ long currentBlockAddress = nextBlockAddress;
+ nextBlockAddress = BlockHeader.NEXT_BLOCK.get(nd, currentBlockAddress);
+ int elementsInBlock = BlockHeader.ELEMENTS_IN_USE.get(nd, currentBlockAddress);
+ destructElements(nd, currentBlockAddress + BlockHeader.BLOCK_HEADER_BYTES, elementsInBlock);
+ db.free(currentBlockAddress, poolId);
+ }
+
+ db.clearRange(headerStartAddress, getRecordSize());
+ } finally {
+ db.getLog().end(this.destructTag);
+ }
+ }
+
+ private void destructElements(Nd nd, long nextElementAddress, int count) {
+ ITypeFactory<T> factory = this.elementType.getFactory();
+
+ int size = getElementSize();
+ while (--count >= 0) {
+ factory.destruct(nd, nextElementAddress);
+ nextElementAddress += size;
+ }
+ }
+}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldManyToOne.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldManyToOne.java
index 41216cfb87..4d3d4b1acb 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldManyToOne.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldManyToOne.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.jdt.internal.core.nd.field;
+import org.eclipse.jdt.internal.core.nd.INdStruct;
import org.eclipse.jdt.internal.core.nd.ITypeFactory;
import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.NdNode;
@@ -23,12 +24,12 @@ import org.eclipse.jdt.internal.core.nd.db.ModificationLog.Tag;
* {@link FieldManyToOne} points to an object, the inverse pointer is automatically inserted into the matching back
* pointer list.
*/
-public class FieldManyToOne<T extends NdNode> extends BaseField implements IDestructableField, IRefCountedField {
+public class FieldManyToOne<T extends INdStruct> extends BaseField implements IDestructableField, IRefCountedField {
public final static FieldPointer TARGET;
public final static FieldInt BACKPOINTER_INDEX;
StructDef<T> targetType;
- final StructDef<? extends NdNode> localType;
+ final StructDef<? extends INdStruct> localType;
FieldOneToMany<?> backPointer;
@SuppressWarnings("rawtypes")
private final static StructDef<FieldManyToOne> type;
@@ -38,6 +39,7 @@ public class FieldManyToOne<T extends NdNode> extends BaseField implements IDest
public final boolean pointsToOwner;
private final Tag putTag;
private final Tag destructTag;
+ private boolean permitsNull = true;
static {
type = StructDef.createAbstract(FieldManyToOne.class);
@@ -47,7 +49,7 @@ public class FieldManyToOne<T extends NdNode> extends BaseField implements IDest
}
@SuppressWarnings({ "unchecked", "rawtypes" })
- private FieldManyToOne(StructDef<? extends NdNode> localType, FieldOneToMany<?> backPointer, boolean pointsToOwner) {
+ private FieldManyToOne(StructDef<? extends INdStruct> localType, FieldOneToMany<?> backPointer, boolean pointsToOwner) {
this.localType = localType;
this.pointsToOwner = pointsToOwner;
@@ -68,7 +70,14 @@ public class FieldManyToOne<T extends NdNode> extends BaseField implements IDest
this.destructTag = ModificationLog.createTag("Destructing " + getFieldName()); //$NON-NLS-1$
}
- public static <T extends NdNode, B extends NdNode> FieldManyToOne<T> create(StructDef<B> builder,
+ public static <T extends INdStruct, B extends INdStruct> FieldManyToOne<T> createNonNull(StructDef<B> builder,
+ FieldOneToMany<B> forwardPointer) {
+ FieldManyToOne<T> result = create(builder, forwardPointer);
+ result.permitsNull = false;
+ return result;
+ }
+
+ public static <T extends INdStruct, B extends INdStruct> FieldManyToOne<T> create(StructDef<B> builder,
FieldOneToMany<B> forwardPointer) {
FieldManyToOne<T> result = new FieldManyToOne<T>(builder, forwardPointer, false);
builder.add(result);
@@ -84,8 +93,17 @@ public class FieldManyToOne<T extends NdNode> extends BaseField implements IDest
* @param forwardPointer the field which holds the pointer in the other direction
* @return a newly constructed field
*/
- public static <T extends NdNode, B extends NdNode> FieldManyToOne<T> createOwner(StructDef<B> builder,
+ public static <T extends INdStruct, B extends INdStruct> FieldManyToOne<T> createOwner(StructDef<B> builder,
FieldOneToMany<B> forwardPointer) {
+ // Although it would work to have a non-NdNode owned in this manner, we currently have no legitimate use-cases
+ // for this to occur. If this happens it is almost certainly an accidental copy-paste error where someone
+ // intended to call create but called this method instead. If we ever discover a legitimate use-case for it,
+ // this could be removed and things would probably still work.
+ if (!NdNode.class.isAssignableFrom(builder.getStructClass())) {
+ throw new IllegalArgumentException(FieldManyToOne.class.getSimpleName() + " can't be the owner of " //$NON-NLS-1$
+ + builder.getStructClass().getSimpleName() + " because the latter isn't a subclass of " //$NON-NLS-1$
+ + NdNode.class.getSimpleName());
+ }
FieldManyToOne<T> result = new FieldManyToOne<T>(builder, forwardPointer, true);
builder.add(result);
@@ -94,12 +112,29 @@ public class FieldManyToOne<T extends NdNode> extends BaseField implements IDest
return result;
}
+ /**
+ * Sets whether or not this field permits nulls to be assigned.
+ *
+ * @param permitted true iff the field permits nulls
+ * @return this
+ */
+ public FieldManyToOne<T> permitNull(boolean permitted) {
+ this.permitsNull = permitted;
+ return this;
+ }
+
public T get(Nd nd, long address) {
return NdNode.load(nd, getAddress(nd, address), this.targetType);
}
public long getAddress(Nd nd, long address) {
- return nd.getDB().getRecPtr(address + this.offset);
+ long result = nd.getDB().getRecPtr(address + this.offset);
+ if (!this.permitsNull && result == 0) {
+ throw nd.describeProblem()
+ .addProblemAddress(this, address)
+ .build("Database contained a null in a non-null field"); //$NON-NLS-1$
+ }
+ return result;
}
/**
@@ -109,8 +144,10 @@ public class FieldManyToOne<T extends NdNode> extends BaseField implements IDest
public void put(Nd nd, long address, T value) {
if (value != null) {
put(nd, address, value.getAddress());
- } else {
+ } else if (this.permitsNull) {
put(nd, address, 0);
+ } else {
+ throw new IllegalArgumentException("Attempted to write a null into a non-null field"); //$NON-NLS-1$
}
}
@@ -153,13 +190,14 @@ public class FieldManyToOne<T extends NdNode> extends BaseField implements IDest
this.backPointer.remove(nd, oldTargetAddress, oldIndex);
- short targetTypeId = NdNode.NODE_TYPE.get(nd, oldTargetAddress);
+ if (this.targetType.isNdNode()) {
+ short targetTypeId = NdNode.NODE_TYPE.get(nd, oldTargetAddress);
+ ITypeFactory<? extends NdNode> typeFactory = nd.getTypeFactory(targetTypeId);
- ITypeFactory<T> typeFactory = nd.getTypeFactory(targetTypeId);
-
- if (typeFactory.getDeletionSemantics() == StructDef.DeletionSemantics.REFCOUNTED
- && typeFactory.isReadyForDeletion(nd, oldTargetAddress)) {
- nd.scheduleDeletion(oldTargetAddress);
+ if (typeFactory.getDeletionSemantics() == StructDef.DeletionSemantics.REFCOUNTED
+ && typeFactory.isReadyForDeletion(nd, oldTargetAddress)) {
+ nd.scheduleDeletion(oldTargetAddress);
+ }
}
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldOneToMany.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldOneToMany.java
index 19c085db46..5b3952fabd 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldOneToMany.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldOneToMany.java
@@ -13,6 +13,7 @@ package org.eclipse.jdt.internal.core.nd.field;
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.jdt.internal.core.nd.INdStruct;
import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.NdNode;
import org.eclipse.jdt.internal.core.nd.RawGrowableArray;
@@ -21,9 +22,9 @@ import org.eclipse.jdt.internal.core.nd.RawGrowableArray;
* Holds the 1 side of a 1..n relationship between two objects. FieldNodePointer and FieldBackPointer fields always go
* together in pairs.
*/
-public class FieldOneToMany<T extends NdNode> extends BaseField implements IDestructableField, IRefCountedField {
+public class FieldOneToMany<T extends INdStruct> extends BaseField implements IDestructableField, IRefCountedField {
public StructDef<T> targetType;
- public final StructDef<? extends NdNode> localType;
+ public final StructDef<? extends INdStruct> localType;
private final RawGrowableArray backPointerArray;
FieldManyToOne<?> forwardPointer;
@@ -32,7 +33,7 @@ public class FieldOneToMany<T extends NdNode> extends BaseField implements IDest
}
@SuppressWarnings({ "rawtypes", "unchecked" })
- private FieldOneToMany(StructDef<? extends NdNode> localType, FieldManyToOne<? extends NdNode> forwardPointer,
+ private FieldOneToMany(StructDef<? extends INdStruct> localType, FieldManyToOne<? extends INdStruct> forwardPointer,
int inlineElements) {
this.localType = localType;
@@ -42,8 +43,8 @@ public class FieldOneToMany<T extends NdNode> extends BaseField implements IDest
"Attempted to construct a FieldBackPointer referring to a forward pointer that is already in use" //$NON-NLS-1$
+ " by another field"); //$NON-NLS-1$
}
- forwardPointer.targetType = (StructDef)localType;
- this.targetType = (StructDef)forwardPointer.localType;
+ forwardPointer.targetType = (StructDef) localType;
+ this.targetType = (StructDef) forwardPointer.localType;
forwardPointer.backPointer = this;
}
this.forwardPointer = forwardPointer;
@@ -64,7 +65,7 @@ public class FieldOneToMany<T extends NdNode> extends BaseField implements IDest
* offer a performance improvement. For relationships that will normally be empty, this should be 0.
* @return the newly constructed backpointer field
*/
- public static <T extends NdNode, B extends NdNode> FieldOneToMany<T> create(StructDef<B> builder,
+ public static <T extends INdStruct, B extends INdStruct> FieldOneToMany<T> create(StructDef<B> builder,
FieldManyToOne<B> forwardPointer, int inlineElementCount) {
FieldOneToMany<T> result = new FieldOneToMany<T>(builder, forwardPointer, inlineElementCount);
builder.add(result);
@@ -73,11 +74,11 @@ public class FieldOneToMany<T extends NdNode> extends BaseField implements IDest
return result;
}
- public static <T extends NdNode, B extends NdNode> FieldOneToMany<T> create(StructDef<B> builder,
+ public static <T extends INdStruct, B extends INdStruct> FieldOneToMany<T> create(StructDef<B> builder,
FieldManyToOne<B> forwardPointer) {
return create(builder, forwardPointer, 0);
}
-
+
public void accept(Nd nd, long address, Visitor<T> visitor) {
int size = size(nd, address);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldOneToOne.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldOneToOne.java
index ca7fa19009..47d1d714dd 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldOneToOne.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/FieldOneToOne.java
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.jdt.internal.core.nd.field;
+import org.eclipse.jdt.internal.core.nd.INdStruct;
import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.NdNode;
import org.eclipse.jdt.internal.core.nd.db.ModificationLog;
@@ -19,7 +20,7 @@ import org.eclipse.jdt.internal.core.nd.db.Database;
/**
* Represents a 1-to-0..1 relationship in a Nd database.
*/
-public class FieldOneToOne<T extends NdNode> extends BaseField implements IDestructableField, IRefCountedField {
+public class FieldOneToOne<T extends INdStruct> extends BaseField implements IDestructableField, IRefCountedField {
public final StructDef<T> nodeType;
FieldOneToOne<?> backPointer;
private boolean pointsToOwner;
@@ -49,7 +50,7 @@ public class FieldOneToOne<T extends NdNode> extends BaseField implements IDestr
this.destructTag = ModificationLog.createTag("Destructing " + getFieldName()); //$NON-NLS-1$
}
- public static <T extends NdNode, B extends NdNode> FieldOneToOne<T> create(StructDef<B> builder,
+ public static <T extends INdStruct, B extends INdStruct> FieldOneToOne<T> create(StructDef<B> builder,
StructDef<T> nodeType, FieldOneToOne<B> forwardPointer) {
FieldOneToOne<T> result = new FieldOneToOne<T>(nodeType, forwardPointer, false);
@@ -58,7 +59,7 @@ public class FieldOneToOne<T extends NdNode> extends BaseField implements IDestr
return result;
}
- public static <T extends NdNode, B extends NdNode> FieldOneToOne<T> createOwner(StructDef<B> builder,
+ public static <T extends INdStruct, B extends INdStruct> FieldOneToOne<T> createOwner(StructDef<B> builder,
StructDef<T> nodeType, FieldOneToOne<B> forwardPointer) {
FieldOneToOne<T> result = new FieldOneToOne<T>(nodeType, forwardPointer, true);
@@ -84,8 +85,8 @@ public class FieldOneToOne<T extends NdNode> extends BaseField implements IDestr
nd.scheduleDeletion(address);
}
} else {
- db.putRecPtr(address + this.offset, target.address);
- db.putRecPtr(target.address + this.backPointer.offset, address);
+ db.putRecPtr(address + this.offset, target.getAddress());
+ db.putRecPtr(target.getAddress() + this.backPointer.offset, address);
}
} finally {
db.getLog().end(this.putTag);
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/IField.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/IField.java
index 6796a46c1e..78a793e4e5 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/IField.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/IField.java
@@ -14,7 +14,15 @@ import org.eclipse.jdt.internal.core.nd.db.Database;
/**
* Represents a single field of a struct in the {@link Database}. Holds metadata for that field
- * and permits laziy initialization of the field offset.
+ * and permits laziy initialization of the field offset. Fields are normally instantiated as static
+ * variables. Collectively, they describe the database schema but they are not associated with any
+ * particular instance of data in the database.
+ * <p>
+ * Fields are temporarily mutable. On construction, a number of attributes (such as offset) are
+ * computed in a second pass or are initialized as other fields are constructed. Generally such
+ * attributes can't be computed in the constructor since they depend on knowledge of other fields
+ * that must be instantiated first. However, once {@link StructDef#done()} has been called on the
+ * last {@link StructDef}, fields are immutable and should not ever be modified again.
*/
public interface IField {
/**
@@ -22,12 +30,20 @@ public interface IField {
* after the sizes of all preceeding fields are known.
*/
void setOffset(int offset);
+
/**
* Returns the size of the field, in bytes.
*/
int getRecordSize();
/**
+ * Returns the required byte alignment for the field.
+ */
+ default int getAlignment() {
+ return 1;
+ }
+
+ /**
* Returns the name of the field. This is mainly used for error messages, debug output, and diagnostic tools.
* Meant to be programmer-readable but not user-readable.
*/
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/StructDef.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/StructDef.java
index b5fddf3426..9fe5571b50 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/StructDef.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/field/StructDef.java
@@ -15,14 +15,18 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.eclipse.jdt.internal.core.nd.IDestructable;
import org.eclipse.jdt.internal.core.nd.ITypeFactory;
import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.db.ModificationLog;
+import org.eclipse.jdt.internal.core.nd.NdNode;
import org.eclipse.jdt.internal.core.nd.db.Database;
+import org.eclipse.jdt.internal.core.nd.db.ModificationLog;
import org.eclipse.jdt.internal.core.nd.db.ModificationLog.Tag;
+import org.eclipse.jdt.internal.core.nd.util.MathUtils;
/**
* Defines a data structure that will appear in the database.
@@ -46,10 +50,11 @@ import org.eclipse.jdt.internal.core.nd.db.ModificationLog.Tag;
public final class StructDef<T> {
Class<T> clazz;
private StructDef<? super T> superClass;
+ private Set<StructDef<?>> dependencies = new HashSet<>();
private List<IField> fields = new ArrayList<>();
private boolean doneCalled;
private boolean offsetsComputed;
- private List<StructDef<? extends T>> subClasses = new ArrayList<>();
+ private List<StructDef<? extends T>> dependents = new ArrayList<>();
private int size;
List<IDestructableField> destructableFields = new ArrayList<>();
boolean refCounted;
@@ -60,6 +65,7 @@ public final class StructDef<T> {
protected boolean hasUserDestructor;
private DeletionSemantics deletionSemantics;
final Tag destructTag;
+ private boolean isNdNode;
public static enum DeletionSemantics {
EXPLICIT, OWNED, REFCOUNTED
@@ -76,9 +82,10 @@ public final class StructDef<T> {
private StructDef(Class<T> clazz, StructDef<? super T> superClass, boolean isAbstract) {
this.destructTag = ModificationLog.createTag("Destructing struct " + clazz.getSimpleName()); //$NON-NLS-1$
this.clazz = clazz;
+ this.isNdNode = NdNode.class.isAssignableFrom(clazz);
this.superClass = superClass;
if (this.superClass != null) {
- this.superClass.subClasses.add(this);
+ addDependency(this.superClass);
}
this.isAbstract = isAbstract;
final String fullyQualifiedClassName = clazz.getName();
@@ -162,6 +169,32 @@ public final class StructDef<T> {
};
}
+ public void addDependency(StructDef<?> newDependency) {
+ if (newDependency.hasIndirectDependent(new HashSet<>(), this)) {
+ throw new IllegalArgumentException("Circular dependency detected. Struct " //$NON-NLS-1$
+ + getStructName() + " and struct " + newDependency.getStructName() //$NON-NLS-1$
+ + " both depend on one another"); //$NON-NLS-1$
+ }
+ if (this.dependencies.add(newDependency)) {
+ this.superClass.dependents.add(this);
+ }
+ }
+
+ private boolean hasIndirectDependent(Set<StructDef<?>> visited, StructDef<?> structDef) {
+ for (StructDef<?> next : this.dependents) {
+ if (!visited.add(next)) {
+ continue;
+ }
+ if (next.equals(structDef)) {
+ return true;
+ }
+ if (next.hasIndirectDependent(visited, structDef)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public Class<T> getStructClass() {
return this.clazz;
}
@@ -217,6 +250,15 @@ public final class StructDef<T> {
return this.deletionSemantics;
}
+ private boolean areAllDependenciesResolved() {
+ for (StructDef<?> next : this.dependencies) {
+ if (!next.areOffsetsComputed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
/**
* Call this once all the fields have been added to the struct definition and it is
* ready to use.
@@ -227,7 +269,7 @@ public final class StructDef<T> {
}
this.doneCalled = true;
- if (this.superClass == null || this.superClass.areOffsetsComputed()) {
+ if (areAllDependenciesResolved()) {
computeOffsets();
}
}
@@ -286,12 +328,13 @@ public final class StructDef<T> {
/**
* Invoked on all StructDef after both {@link #done()} has been called on the struct and
- * {@link #computeOffsets()} has been called on their base class.
+ * {@link #computeOffsets()} has been called on every dependency of this struct.
*/
private void computeOffsets() {
int offset = this.superClass == null ? 0 : this.superClass.size();
for (IField next : this.fields) {
+ offset = MathUtils.roundUpToNearestMultiple(offset, next.getAlignment());
next.setOffset(offset);
offset += next.getRecordSize();
}
@@ -320,7 +363,7 @@ public final class StructDef<T> {
this.offsetsComputed = true;
- for (StructDef<? extends T> next : this.subClasses) {
+ for (StructDef<? extends T> next : this.dependents) {
if (next.doneCalled) {
next.computeOffsets();
}
@@ -409,6 +452,10 @@ public final class StructDef<T> {
}
}
+ public boolean isNdNode() {
+ return this.isNdNode;
+ }
+
public int getNumFields() {
return this.fields.size();
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/ClassFileToIndexConverter.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/ClassFileToIndexConverter.java
index 38cacb1d98..2ba44b183c 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/ClassFileToIndexConverter.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/ClassFileToIndexConverter.java
@@ -36,11 +36,6 @@ import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.java.JavaIndex;
import org.eclipse.jdt.internal.core.nd.java.JavaNames;
import org.eclipse.jdt.internal.core.nd.java.NdAnnotation;
-import org.eclipse.jdt.internal.core.nd.java.NdAnnotationInConstant;
-import org.eclipse.jdt.internal.core.nd.java.NdAnnotationInMethod;
-import org.eclipse.jdt.internal.core.nd.java.NdAnnotationInMethodParameter;
-import org.eclipse.jdt.internal.core.nd.java.NdAnnotationInType;
-import org.eclipse.jdt.internal.core.nd.java.NdAnnotationInVariable;
import org.eclipse.jdt.internal.core.nd.java.NdAnnotationValuePair;
import org.eclipse.jdt.internal.core.nd.java.NdBinding;
import org.eclipse.jdt.internal.core.nd.java.NdComplexTypeSignature;
@@ -50,17 +45,12 @@ import org.eclipse.jdt.internal.core.nd.java.NdConstantArray;
import org.eclipse.jdt.internal.core.nd.java.NdConstantClass;
import org.eclipse.jdt.internal.core.nd.java.NdConstantEnum;
import org.eclipse.jdt.internal.core.nd.java.NdMethod;
-import org.eclipse.jdt.internal.core.nd.java.NdMethodException;
import org.eclipse.jdt.internal.core.nd.java.NdMethodId;
import org.eclipse.jdt.internal.core.nd.java.NdMethodParameter;
import org.eclipse.jdt.internal.core.nd.java.NdResourceFile;
import org.eclipse.jdt.internal.core.nd.java.NdType;
import org.eclipse.jdt.internal.core.nd.java.NdTypeAnnotation;
-import org.eclipse.jdt.internal.core.nd.java.NdTypeAnnotationInMethod;
-import org.eclipse.jdt.internal.core.nd.java.NdTypeAnnotationInType;
-import org.eclipse.jdt.internal.core.nd.java.NdTypeAnnotationInVariable;
import org.eclipse.jdt.internal.core.nd.java.NdTypeArgument;
-import org.eclipse.jdt.internal.core.nd.java.NdTypeBound;
import org.eclipse.jdt.internal.core.nd.java.NdTypeId;
import org.eclipse.jdt.internal.core.nd.java.NdTypeInterface;
import org.eclipse.jdt.internal.core.nd.java.NdTypeParameter;
@@ -77,7 +67,7 @@ public final class ClassFileToIndexConverter {
private static final char[] COMMA = new char[]{','};
private static final char[][] EMPTY_CHAR_ARRAY_ARRAY = new char[0][];
private static final boolean ENABLE_LOGGING = false;
- private static final char[] EMPTY_CHAR_ARRAY = new char[0];
+ static final char[] EMPTY_CHAR_ARRAY = new char[0];
private static final char[] PATH_SEPARATOR = new char[]{'/'};
private static final char[] ARRAY_FIELD_DESCRIPTOR_PREFIX = new char[] { '[' };
private NdResourceFile resource;
@@ -135,8 +125,9 @@ public final class ClassFileToIndexConverter {
IBinaryTypeAnnotation[] typeAnnotations = binaryType.getTypeAnnotations();
if (typeAnnotations != null) {
+ type.allocateTypeAnnotations(typeAnnotations.length);
for (IBinaryTypeAnnotation typeAnnotation : typeAnnotations) {
- NdTypeAnnotationInType annotation = new NdTypeAnnotationInType(getNd(), type);
+ NdTypeAnnotation annotation = type.createTypeAnnotation();
initTypeAnnotation(annotation, typeAnnotation);
}
@@ -194,6 +185,7 @@ public final class ClassFileToIndexConverter {
IBinaryField[] fields = binaryType.getFields();
if (fields != null) {
+ type.allocateVariables(fields.length);
for (IBinaryField nextField : fields) {
addField(type, nextField);
}
@@ -251,8 +243,9 @@ public final class ClassFileToIndexConverter {
private void attachAnnotations(NdMethod method, IBinaryAnnotation[] annotations) {
if (annotations != null) {
+ method.allocateAnnotations(annotations.length);
for (IBinaryAnnotation next : annotations) {
- NdAnnotationInMethod annotation = new NdAnnotationInMethod(getNd(), method);
+ NdAnnotation annotation = method.createAnnotation();
initAnnotation(annotation, next);
}
}
@@ -260,8 +253,9 @@ public final class ClassFileToIndexConverter {
private void attachAnnotations(NdType type, IBinaryAnnotation[] annotations) {
if (annotations != null) {
+ type.allocateAnnotations(annotations.length);
for (IBinaryAnnotation next : annotations) {
- NdAnnotationInType annotation = new NdAnnotationInType(getNd(), type);
+ NdAnnotation annotation = type.createAnnotation();
initAnnotation(annotation, next);
}
}
@@ -269,8 +263,9 @@ public final class ClassFileToIndexConverter {
private void attachAnnotations(NdVariable variable, IBinaryAnnotation[] annotations) {
if (annotations != null) {
+ variable.allocateAnnotations(annotations.length);
for (IBinaryAnnotation next : annotations) {
- NdAnnotationInVariable annotation = new NdAnnotationInVariable(getNd(), variable);
+ NdAnnotation annotation = variable.createAnnotation();
initAnnotation(annotation, next);
}
}
@@ -278,8 +273,9 @@ public final class ClassFileToIndexConverter {
private void attachAnnotations(NdMethodParameter variable, IBinaryAnnotation[] annotations) {
if (annotations != null) {
+ variable.allocateAnnotations(annotations.length);
for (IBinaryAnnotation next : annotations) {
- NdAnnotationInMethodParameter annotation = new NdAnnotationInMethodParameter(getNd(), variable);
+ NdAnnotation annotation = variable.createAnnotation();
initAnnotation(annotation, next);
}
}
@@ -306,8 +302,9 @@ public final class ClassFileToIndexConverter {
IBinaryTypeAnnotation[] typeAnnotations = next.getTypeAnnotations();
if (typeAnnotations != null) {
+ method.allocateTypeAnnotations(typeAnnotations.length);
for (IBinaryTypeAnnotation typeAnnotation : typeAnnotations) {
- NdTypeAnnotationInMethod annotation = new NdTypeAnnotationInMethod(getNd(), method);
+ NdTypeAnnotation annotation = method.createTypeAnnotation();
initTypeAnnotation(annotation, typeAnnotation);
}
@@ -349,6 +346,10 @@ public final class ClassFileToIndexConverter {
int parameterNameIdx = 0;
int annotatedParametersCount = next.getAnnotatedParametersCount();
+ int namedParameterCount = parameterNames == null ? 0 : parameterNames.length;
+ int estimatedParameterCount = Math.max(Math.max(Math.max(numArgumentsInGenericSignature, namedParameterCount),
+ annotatedParametersCount), parameterFieldDescriptors.size());
+ method.allocateParameters(estimatedParameterCount);
short descriptorParameterIdx = 0;
char[] binaryTypeName = binaryType.getName();
@@ -367,8 +368,8 @@ public final class ClassFileToIndexConverter {
if (isCompilerDefined && !compilerDefinedParametersAreIncludedInSignature) {
nextFieldSignature = new SignatureWrapper(nextFieldDescriptor);
}
- NdMethodParameter parameter = new NdMethodParameter(method,
- createTypeSignature(nextFieldSignature, nextFieldDescriptor));
+ NdMethodParameter parameter = method.createNewParameter();
+ parameter.setType(createTypeSignature(nextFieldSignature, nextFieldDescriptor));
parameter.setCompilerDefined(isCompilerDefined);
@@ -378,7 +379,7 @@ public final class ClassFileToIndexConverter {
attachAnnotations(parameter, parameterAnnotations);
}
- if (!isCompilerDefined && parameterNames != null && parameterNames.length > parameterNameIdx) {
+ if (!isCompilerDefined && namedParameterCount > parameterNameIdx) {
parameter.setName(parameterNames[parameterNameIdx++]);
}
descriptorParameterIdx++;
@@ -393,11 +394,12 @@ public final class ClassFileToIndexConverter {
if (exceptionTypes == null) {
exceptionTypes = CharArrayUtils.EMPTY_ARRAY_OF_CHAR_ARRAYS;
}
+ method.allocateExceptions(exceptionTypes.length);
int throwsIdx = 0;
if (hasExceptionsInSignature) {
while (hasAnotherException(signature)) {
signature.start++;
- new NdMethodException(method, createTypeSignature(signature,
+ method.createException(createTypeSignature(signature,
JavaNames.binaryNameToFieldDescriptor(exceptionTypes[throwsIdx])));
throwsIdx++;
}
@@ -405,7 +407,7 @@ public final class ClassFileToIndexConverter {
for (;throwsIdx < exceptionTypes.length; throwsIdx++) {
char[] fieldDescriptor = JavaNames.binaryNameToFieldDescriptor(exceptionTypes[throwsIdx]);
SignatureWrapper convertedWrapper = new SignatureWrapper(fieldDescriptor);
- new NdMethodException(method, createTypeSignature(convertedWrapper,
+ method.createException(createTypeSignature(convertedWrapper,
JavaNames.binaryNameToFieldDescriptor(exceptionTypes[throwsIdx])));
}
}
@@ -439,7 +441,7 @@ public final class ClassFileToIndexConverter {
* Adds the given field to the given type
*/
private void addField(NdType type, IBinaryField nextField) throws CoreException {
- NdVariable variable = new NdVariable(type);
+ NdVariable variable = type.createVariable();
variable.setName(nextField.getName());
@@ -455,18 +457,23 @@ public final class ClassFileToIndexConverter {
IBinaryTypeAnnotation[] typeAnnotations = nextField.getTypeAnnotations();
if (typeAnnotations != null) {
+ variable.allocateTypeAnnotations(typeAnnotations.length);
for (IBinaryTypeAnnotation next : typeAnnotations) {
- NdTypeAnnotationInVariable annotation = new NdTypeAnnotationInVariable(getNd(), variable);
+ NdTypeAnnotation annotation = variable.createTypeAnnotation();
initTypeAnnotation(annotation, next);
}
}
variable.setType(createTypeSignature(nextTypeSignature, nextField.getTypeName()));
variable.setTagBits(nextField.getTagBits());
+ }
- // char[] fieldDescriptor = nextField.getTypeName();
- // // DO NOT SUBMIT:
- // IBinaryField bf = IndexBinaryType.createBinaryField(variable);
+ private static class TypeParameter {
+ public TypeParameter() {
+ }
+ public List<NdTypeSignature> bounds = new ArrayList<>();
+ public char[] identifier = ClassFileToIndexConverter.EMPTY_CHAR_ARRAY;
+ public boolean firstBoundIsClass;
}
/**
@@ -482,25 +489,40 @@ public final class ClassFileToIndexConverter {
return;
}
+ List<TypeParameter> typeParameters = new ArrayList<>();
+
int indexOfClosingBracket = wrapper.skipAngleContents(wrapper.start) - 1;
wrapper.start++;
- NdTypeParameter parameter = null;
+ TypeParameter parameter = null;
while (wrapper.start < indexOfClosingBracket) {
int colonPos = CharOperation.indexOf(':', genericSignature, wrapper.start, indexOfClosingBracket);
if (colonPos > wrapper.start) {
char[] identifier = CharOperation.subarray(genericSignature, wrapper.start, colonPos);
- parameter = new NdTypeParameter(type, identifier);
+ parameter = new TypeParameter();
+ typeParameters.add(parameter);
+ parameter.identifier = identifier;
wrapper.start = colonPos + 1;
// The first bound is a class as long as it doesn't start with a double-colon
- parameter.setFirstBoundIsClass(wrapper.charAtStart() != ':');
+ parameter.firstBoundIsClass = (wrapper.charAtStart() != ':');
}
skipChar(wrapper, ':');
NdTypeSignature boundSignature = createTypeSignature(wrapper, JAVA_LANG_OBJECT_FIELD_DESCRIPTOR);
- new NdTypeBound(parameter, boundSignature);
+ parameter.bounds.add(boundSignature);
+ }
+
+ type.allocateTypeParameters(typeParameters.size());
+ for (TypeParameter param : typeParameters) {
+ NdTypeParameter ndParam = type.createTypeParameter();
+ ndParam.setIdentifier(param.identifier);
+ ndParam.setFirstBoundIsClass(param.firstBoundIsClass);
+ ndParam.allocateBounds(param.bounds.size());
+ for (NdTypeSignature bound : param.bounds) {
+ ndParam.createBound(bound);
+ }
}
skipChar(wrapper, '>');
@@ -854,8 +876,9 @@ public final class ClassFileToIndexConverter {
IBinaryElementValuePair[] pairs = next.getElementValuePairs();
if (pairs != null) {
+ annotation.allocateValuePairs(pairs.length);
for (IBinaryElementValuePair element : pairs) {
- NdAnnotationValuePair nextPair = new NdAnnotationValuePair(annotation, element.getName());
+ NdAnnotationValuePair nextPair = annotation.createValuePair(element.getName());
nextPair.setValue(createConstantFromMixedType(element.getValue()));
}
}
@@ -894,9 +917,9 @@ public final class ClassFileToIndexConverter {
} else if (value instanceof IBinaryAnnotation) {
IBinaryAnnotation binaryAnnotation = (IBinaryAnnotation) value;
- NdAnnotationInConstant annotation = new NdAnnotationInConstant(getNd());
- initAnnotation(annotation, binaryAnnotation);
- return NdConstantAnnotation.create(getNd(), annotation);
+ NdConstantAnnotation constant = new NdConstantAnnotation(getNd());
+ initAnnotation(constant.getValue(), binaryAnnotation);
+ return constant;
} else if (value instanceof Object[]) {
NdConstantArray result = new NdConstantArray(getNd());
Object[] array = (Object[]) value;
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java
index 877713cb0f..08bd027304 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java
@@ -75,7 +75,6 @@ import org.eclipse.jdt.internal.core.nd.java.NdResourceFile;
import org.eclipse.jdt.internal.core.nd.java.NdType;
import org.eclipse.jdt.internal.core.nd.java.NdTypeId;
import org.eclipse.jdt.internal.core.nd.java.NdWorkspaceLocation;
-import org.eclipse.jdt.internal.core.nd.java.NdZipEntry;
import org.eclipse.jdt.internal.core.nd.java.TypeRef;
import org.eclipse.jdt.internal.core.nd.java.model.BinaryTypeDescriptor;
import org.eclipse.jdt.internal.core.nd.java.model.BinaryTypeFactory;
@@ -704,6 +703,13 @@ public final class Indexer {
}
subMonitor.setWorkRemaining(zipFile.size());
+ // Preallocate memory for the zipfile entries
+ this.nd.acquireWriteLock(subMonitor.split(5));
+ try {
+ resourceFile.allocateZipEntries(zipFile.size());
+ } finally {
+ this.nd.releaseWriteLock();
+ }
for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements();) {
SubMonitor nextEntry = subMonitor.split(1).setWorkRemaining(2);
ZipEntry member = e.nextElement();
@@ -717,7 +723,7 @@ public final class Indexer {
Package.logInfo("Inserting non-class file " + fileName + " into " //$NON-NLS-1$//$NON-NLS-2$
+ resourceFile.getLocation().getString() + " " + resourceFile.address); //$NON-NLS-1$
}
- new NdZipEntry(resourceFile, fileName);
+ resourceFile.addZipEntry(fileName);
if (fileName.equals("META-INF/MANIFEST.MF")) { //$NON-NLS-1$
try (InputStream inputStream = zipFile.getInputStream(member)) {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/JavaIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/JavaIndex.java
index 2c416a6a47..9c9f94a90d 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/JavaIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/JavaIndex.java
@@ -38,9 +38,9 @@ import org.eclipse.jdt.internal.core.nd.util.CharArrayUtils;
public class JavaIndex {
// Version constants
- static final int CURRENT_VERSION = Nd.version(1, 47);
- static final int MAX_SUPPORTED_VERSION = Nd.version(1, 47);
- static final int MIN_SUPPORTED_VERSION = Nd.version(1, 47);
+ static final int CURRENT_VERSION = Nd.version(1, 48);
+ static final int MAX_SUPPORTED_VERSION = Nd.version(1, 48);
+ static final int MIN_SUPPORTED_VERSION = Nd.version(1, 48);
// Fields for the search header
public static final FieldSearchIndex<NdResourceFile> FILES;
@@ -289,13 +289,7 @@ public class JavaIndex {
static NdNodeTypeRegistry<NdNode> createTypeRegistry() {
NdNodeTypeRegistry<NdNode> registry = new NdNodeTypeRegistry<>();
- registry.register(0x0001, NdAnnotation.type.getFactory());
- registry.register(0x0004, NdAnnotationInConstant.type.getFactory());
- registry.register(0x0008, NdAnnotationInMethod.type.getFactory());
- registry.register(0x000c, NdAnnotationInMethodParameter.type.getFactory());
- registry.register(0x0010, NdAnnotationInType.type.getFactory());
- registry.register(0x0014, NdAnnotationInVariable.type.getFactory());
- registry.register(0x0020, NdAnnotationValuePair.type.getFactory());
+
registry.register(0x0028, NdBinding.type.getFactory());
registry.register(0x0030, NdComplexTypeSignature.type.getFactory());
registry.register(0x0038, NdConstant.type.getFactory());
@@ -314,25 +308,16 @@ public class JavaIndex {
registry.register(0x0100, NdConstantString.type.getFactory());
registry.register(0x0110, NdMethod.type.getFactory());
registry.register(0x0118, NdMethodAnnotationData.type.getFactory());
- registry.register(0x0120, NdMethodException.type.getFactory());
registry.register(0x0130, NdMethodId.type.getFactory());
- registry.register(0x0140, NdMethodParameter.type.getFactory());
registry.register(0x0150, NdResourceFile.type.getFactory());
registry.register(0x0170, NdType.type.getFactory());
- registry.register(0x0180, NdTypeAnnotation.type.getFactory());
- registry.register(0x0184, NdTypeAnnotationInMethod.type.getFactory());
- registry.register(0x0188, NdTypeAnnotationInType.type.getFactory());
- registry.register(0x018c, NdTypeAnnotationInVariable.type.getFactory());
registry.register(0x0190, NdTypeArgument.type.getFactory());
- registry.register(0x0194, NdTypeBound.type.getFactory());
registry.register(0x01A0, NdTypeInterface.type.getFactory());
- registry.register(0x01B0, NdTypeParameter.type.getFactory());
registry.register(0x01C0, NdTypeSignature.type.getFactory());
registry.register(0x01D0, NdTypeId.type.getFactory());
registry.register(0x01E0, NdTypeInterface.type.getFactory());
registry.register(0x01F0, NdVariable.type.getFactory());
registry.register(0x0200, NdWorkspaceLocation.type.getFactory());
- registry.register(0x0210, NdZipEntry.type.getFactory());
return registry;
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotation.java
index 9715c100e1..7248ce4708 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotation.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotation.java
@@ -13,22 +13,22 @@ package org.eclipse.jdt.internal.core.nd.java;
import java.util.List;
import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.NdNode;
+import org.eclipse.jdt.internal.core.nd.NdStruct;
+import org.eclipse.jdt.internal.core.nd.field.FieldList;
import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
-import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
-public class NdAnnotation extends NdNode {
+public class NdAnnotation extends NdStruct {
public static final FieldManyToOne<NdTypeSignature> ANNOTATION_TYPE;
- public static final FieldOneToMany<NdAnnotationValuePair> ELEMENT_VALUE_PAIRS;
+ public static final FieldList<NdAnnotationValuePair> ELEMENT_VALUE_PAIRS;
@SuppressWarnings("hiding")
public static final StructDef<NdAnnotation> type;
static {
- type = StructDef.create(NdAnnotation.class, NdNode.type);
+ type = StructDef.create(NdAnnotation.class, NdStruct.type);
ANNOTATION_TYPE = FieldManyToOne.create(type, NdTypeSignature.ANNOTATIONS_OF_THIS_TYPE);
- ELEMENT_VALUE_PAIRS = FieldOneToMany.create(type, NdAnnotationValuePair.APPLIES_TO);
+ ELEMENT_VALUE_PAIRS = FieldList.create(type, NdAnnotationValuePair.type);
type.done();
}
@@ -36,10 +36,6 @@ public class NdAnnotation extends NdNode {
super(nd, address);
}
- public NdAnnotation(Nd nd) {
- super(nd);
- }
-
public NdTypeSignature getType() {
return ANNOTATION_TYPE.get(getNd(), this.address);
}
@@ -51,4 +47,14 @@ public class NdAnnotation extends NdNode {
public List<NdAnnotationValuePair> getElementValuePairs() {
return ELEMENT_VALUE_PAIRS.asList(getNd(), this.address);
}
+
+ public NdAnnotationValuePair createValuePair(char[] name) {
+ NdAnnotationValuePair result = ELEMENT_VALUE_PAIRS.append(getNd(), getAddress());
+ result.setName(name);
+ return result;
+ }
+
+ public void allocateValuePairs(int length) {
+ ELEMENT_VALUE_PAIRS.allocate(getNd(), getAddress(), length);
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInConstant.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInConstant.java
deleted file mode 100644
index d3ee914d11..0000000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInConstant.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2016 Google, Inc and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.nd.java;
-
-import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.field.FieldOneToOne;
-import org.eclipse.jdt.internal.core.nd.field.StructDef;
-
-public class NdAnnotationInConstant extends NdAnnotation {
- public static final FieldOneToOne<NdConstantAnnotation> OWNER;
-
- @SuppressWarnings("hiding")
- public static final StructDef<NdAnnotationInConstant> type;
-
- static {
- type = StructDef.create(NdAnnotationInConstant.class, NdAnnotation.type);
- OWNER = FieldOneToOne.createOwner(type, NdConstantAnnotation.type, NdConstantAnnotation.VALUE);
- type.done();
- }
-
- public NdAnnotationInConstant(Nd nd, long address) {
- super(nd, address);
- }
-
- public NdAnnotationInConstant(Nd nd) {
- super(nd);
- }
-
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInMethod.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInMethod.java
deleted file mode 100644
index c1b524ec79..0000000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInMethod.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2016 Google, Inc and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.nd.java;
-
-import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
-import org.eclipse.jdt.internal.core.nd.field.StructDef;
-
-public class NdAnnotationInMethod extends NdAnnotation {
- public static final FieldManyToOne<NdMethodAnnotationData> OWNER;
-
- @SuppressWarnings("hiding")
- public static final StructDef<NdAnnotationInMethod> type;
-
- static {
- type = StructDef.create(NdAnnotationInMethod.class, NdAnnotation.type);
- OWNER = FieldManyToOne.createOwner(type, NdMethodAnnotationData.ANNOTATIONS);
- type.done();
- }
-
- public NdAnnotationInMethod(Nd nd, long address) {
- super(nd, address);
- }
-
- public NdAnnotationInMethod(Nd nd, NdMethod owner) {
- super(nd);
-
- OWNER.put(getNd(), this.address, owner.createAnnotationData());
- }
-
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInMethodParameter.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInMethodParameter.java
deleted file mode 100644
index 0a4f3fb688..0000000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInMethodParameter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2016 Google, Inc and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.nd.java;
-
-import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
-import org.eclipse.jdt.internal.core.nd.field.StructDef;
-
-public class NdAnnotationInMethodParameter extends NdAnnotation {
- public static final FieldManyToOne<NdMethodParameter> OWNER;
-
- @SuppressWarnings("hiding")
- public static final StructDef<NdAnnotationInMethodParameter> type;
-
- static {
- type = StructDef.create(NdAnnotationInMethodParameter.class, NdAnnotation.type);
- OWNER = FieldManyToOne.createOwner(type, NdMethodParameter.ANNOTATIONS);
- type.done();
- }
-
- public NdAnnotationInMethodParameter(Nd nd, long address) {
- super(nd, address);
- }
-
- public NdAnnotationInMethodParameter(Nd nd, NdMethodParameter owner) {
- super(nd);
-
- OWNER.put(getNd(), this.address, owner);
- }
-
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInType.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInType.java
deleted file mode 100644
index c220ed9f01..0000000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInType.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2016 Google, Inc and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.nd.java;
-
-import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
-import org.eclipse.jdt.internal.core.nd.field.StructDef;
-
-public class NdAnnotationInType extends NdAnnotation {
- public static final FieldManyToOne<NdType> OWNER;
-
- @SuppressWarnings("hiding")
- public static final StructDef<NdAnnotationInType> type;
-
- static {
- type = StructDef.create(NdAnnotationInType.class, NdAnnotation.type);
- OWNER = FieldManyToOne.createOwner(type, NdType.ANNOTATIONS);
- type.done();
- }
-
- public NdAnnotationInType(Nd nd, long address) {
- super(nd, address);
- }
-
- public NdAnnotationInType(Nd nd, NdType owner) {
- super(nd);
-
- OWNER.put(getNd(), this.address, owner);
- }
-
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInVariable.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInVariable.java
deleted file mode 100644
index 378b2d44a2..0000000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationInVariable.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2016 Google, Inc and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.nd.java;
-
-import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
-import org.eclipse.jdt.internal.core.nd.field.StructDef;
-
-public class NdAnnotationInVariable extends NdAnnotation {
- public static final FieldManyToOne<NdVariable> OWNER;
-
- @SuppressWarnings("hiding")
- public static final StructDef<NdAnnotationInVariable> type;
-
- static {
- type = StructDef.create(NdAnnotationInVariable.class, NdAnnotation.type);
- OWNER = FieldManyToOne.createOwner(type, NdVariable.ANNOTATIONS);
- type.done();
- }
-
- public NdAnnotationInVariable(Nd nd, long address) {
- super(nd, address);
- }
-
- public NdAnnotationInVariable(Nd nd, NdVariable owner) {
- super(nd);
-
- OWNER.put(getNd(), this.address, owner);
- }
-
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationValuePair.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationValuePair.java
index 303a0bcb61..eb5d3c20a8 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationValuePair.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdAnnotationValuePair.java
@@ -11,15 +11,13 @@
package org.eclipse.jdt.internal.core.nd.java;
import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.NdNode;
+import org.eclipse.jdt.internal.core.nd.NdStruct;
import org.eclipse.jdt.internal.core.nd.db.IString;
-import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
import org.eclipse.jdt.internal.core.nd.field.FieldOneToOne;
import org.eclipse.jdt.internal.core.nd.field.FieldString;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
-public class NdAnnotationValuePair extends NdNode {
- public static final FieldManyToOne<NdAnnotation> APPLIES_TO;
+public class NdAnnotationValuePair extends NdStruct {
public static final FieldString NAME;
public static final FieldOneToOne<NdConstant> VALUE;
@@ -27,8 +25,7 @@ public class NdAnnotationValuePair extends NdNode {
public static final StructDef<NdAnnotationValuePair> type;
static {
- type = StructDef.create(NdAnnotationValuePair.class, NdNode.type);
- APPLIES_TO = FieldManyToOne.createOwner(type, NdAnnotation.ELEMENT_VALUE_PAIRS);
+ type = StructDef.create(NdAnnotationValuePair.class, NdStruct.type);
NAME = type.addString();
VALUE = FieldOneToOne.create(type, NdConstant.type, NdConstant.PARENT_ANNOTATION_VALUE);
type.done();
@@ -38,22 +35,11 @@ public class NdAnnotationValuePair extends NdNode {
super(nd, address);
}
- public NdAnnotationValuePair(NdAnnotation annotation, char[] name) {
- super(annotation.getNd());
- Nd nd = annotation.getNd();
- APPLIES_TO.put(nd, this.address, annotation);
- NAME.put(nd, this.address, name);
- }
-
- public NdAnnotation getAnnotation() {
- return APPLIES_TO.get(getNd(), this.address);
- }
-
public IString getName() {
return NAME.get(getNd(), this.address);
}
- public void setName(String name) {
+ public void setName(char[] name) {
NAME.put(getNd(), this.address, name);
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdBinding.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdBinding.java
index 3c48fc92db..6fb38a9bf2 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdBinding.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdBinding.java
@@ -17,7 +17,7 @@ import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.NdNode;
import org.eclipse.jdt.internal.core.nd.field.FieldInt;
-import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany;
+import org.eclipse.jdt.internal.core.nd.field.FieldList;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
@@ -26,8 +26,7 @@ import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
*/
public abstract class NdBinding extends NdNode implements IAdaptable {
public static final FieldInt MODIFIERS;
- public static final FieldOneToMany<NdTypeParameter> TYPE_PARAMETERS;
- public static final FieldOneToMany<NdVariable> VARIABLES;
+ public static final FieldList<NdTypeParameter> TYPE_PARAMETERS;
@SuppressWarnings("hiding")
public static final StructDef<NdBinding> type;
@@ -35,8 +34,7 @@ public abstract class NdBinding extends NdNode implements IAdaptable {
static {
type = StructDef.create(NdBinding.class, NdNode.type);
MODIFIERS = type.addInt();
- TYPE_PARAMETERS = FieldOneToMany.create(type, NdTypeParameter.PARENT);
- VARIABLES = FieldOneToMany.create(type, NdVariable.PARENT);
+ TYPE_PARAMETERS = FieldList.create(type, NdTypeParameter.type);
type.done();
}
@@ -48,10 +46,6 @@ public abstract class NdBinding extends NdNode implements IAdaptable {
super(nd);
}
- public List<NdVariable> getVariables() {
- return VARIABLES.asList(getNd(), this.address);
- }
-
/**
* Tests whether this binding has one of the flags defined in {@link Flags}
*/
@@ -106,4 +100,12 @@ public abstract class NdBinding extends NdNode implements IAdaptable {
public List<NdTypeParameter> getTypeParameters() {
return TYPE_PARAMETERS.asList(getNd(), this.address);
}
+
+ public NdTypeParameter createTypeParameter() {
+ return TYPE_PARAMETERS.append(getNd(), getAddress());
+ }
+
+ public void allocateTypeParameters(int elements) {
+ TYPE_PARAMETERS.allocate(getNd(), getAddress(), elements);
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdConstantAnnotation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdConstantAnnotation.java
index a231458df6..35a0da423b 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdConstantAnnotation.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdConstantAnnotation.java
@@ -12,18 +12,18 @@ package org.eclipse.jdt.internal.core.nd.java;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.field.FieldOneToOne;
+import org.eclipse.jdt.internal.core.nd.field.Field;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
public final class NdConstantAnnotation extends NdConstant {
- public static final FieldOneToOne<NdAnnotationInConstant> VALUE;
+ public static final Field<NdAnnotation> VALUE;
@SuppressWarnings("hiding")
public static StructDef<NdConstantAnnotation> type;
static {
type = StructDef.create(NdConstantAnnotation.class, NdConstant.type);
- VALUE = FieldOneToOne.create(type, NdAnnotationInConstant.type, NdAnnotationInConstant.OWNER);
+ VALUE = Field.create(type, NdAnnotation.type);
type.done();
}
@@ -31,20 +31,10 @@ public final class NdConstantAnnotation extends NdConstant {
super(nd, address);
}
- protected NdConstantAnnotation(Nd nd) {
+ public NdConstantAnnotation(Nd nd) {
super(nd);
}
- public static NdConstantAnnotation create(Nd nd, NdAnnotationInConstant value) {
- NdConstantAnnotation result = new NdConstantAnnotation(nd);
- result.setValue(value);
- return result;
- }
-
- public void setValue(NdAnnotationInConstant value) {
- VALUE.put(getNd(), this.address, value);
- }
-
public NdAnnotation getValue() {
return VALUE.get(getNd(), this.address);
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethod.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethod.java
index d7d49b8c24..2ff6c3edfc 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethod.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethod.java
@@ -14,6 +14,7 @@ import java.util.Collections;
import java.util.List;
import org.eclipse.jdt.internal.core.nd.Nd;
+import org.eclipse.jdt.internal.core.nd.field.FieldList;
import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany;
import org.eclipse.jdt.internal.core.nd.field.FieldOneToOne;
@@ -27,9 +28,9 @@ public class NdMethod extends NdBinding {
public static final FieldShort METHOD_FLAGS;
public static final FieldManyToOne<NdType> PARENT;
public static final FieldOneToMany<NdVariable> DECLARED_VARIABLES;
- public static final FieldOneToMany<NdMethodParameter> PARAMETERS;
+ public static final FieldList<NdMethodParameter> PARAMETERS;
public static final FieldOneToOne<NdConstant> DEFAULT_VALUE;
- public static final FieldOneToMany<NdMethodException> EXCEPTIONS;
+ public static final FieldList<NdMethodException> EXCEPTIONS;
public static final FieldManyToOne<NdTypeSignature> RETURN_TYPE;
public static final FieldOneToOne<NdMethodAnnotationData> ANNOTATION_DATA;
@@ -41,10 +42,10 @@ public class NdMethod extends NdBinding {
METHOD_ID = FieldManyToOne.create(type, NdMethodId.METHODS);
METHOD_FLAGS = type.addShort();
PARENT = FieldManyToOne.createOwner(type, NdType.METHODS);
- PARAMETERS = FieldOneToMany.create(type, NdMethodParameter.PARENT);
+ PARAMETERS = FieldList.create(type, NdMethodParameter.type);
DECLARED_VARIABLES = FieldOneToMany.create(type, NdVariable.DECLARING_METHOD);
DEFAULT_VALUE = FieldOneToOne.create(type, NdConstant.type, NdConstant.PARENT_METHOD);
- EXCEPTIONS = FieldOneToMany.create(type, NdMethodException.PARENT);
+ EXCEPTIONS = FieldList.create(type, NdMethodException.type);
RETURN_TYPE = FieldManyToOne.create(type, NdTypeSignature.USED_AS_RETURN_TYPE);
ANNOTATION_DATA = FieldOneToOne.create(type, NdMethodAnnotationData.type, NdMethodAnnotationData.METHOD);
type.done();
@@ -63,6 +64,14 @@ public class NdMethod extends NdBinding {
PARENT.put(getNd(), this.address, parent);
}
+ public NdMethodParameter createNewParameter() {
+ return PARAMETERS.append(getNd(), getAddress());
+ }
+
+ public void allocateParameters(int numParameters) {
+ PARAMETERS.allocate(this.nd, this.address, numParameters);
+ }
+
public NdMethodId getMethodId() {
return METHOD_ID.get(getNd(), this.address);
}
@@ -90,7 +99,7 @@ public class NdMethod extends NdBinding {
return PARAMETERS.asList(getNd(), this.address);
}
- public List<NdAnnotationInMethod> getAnnotations() {
+ public List<NdAnnotation> getAnnotations() {
NdMethodAnnotationData annotationData = getAnnotationData();
if (annotationData != null) {
return annotationData.getAnnotations();
@@ -114,7 +123,7 @@ public class NdMethod extends NdBinding {
METHOD_ID.put(getNd(), this.address, methodId);
}
- public List<NdTypeAnnotationInMethod> getTypeAnnotations() {
+ public List<NdTypeAnnotation> getTypeAnnotations() {
NdMethodAnnotationData annotationData = getAnnotationData();
if (annotationData != null) {
return annotationData.getTypeAnnotations();
@@ -220,4 +229,34 @@ public class NdMethod extends NdBinding {
private NdMethodAnnotationData getAnnotationData() {
return ANNOTATION_DATA.get(getNd(), getAddress());
}
+
+ public NdMethodException createException(NdTypeSignature createTypeSignature) {
+ NdMethodException result = EXCEPTIONS.append(getNd(), getAddress());
+ result.setExceptionType(createTypeSignature);
+ return result;
+ }
+
+ public void allocateExceptions(int length) {
+ EXCEPTIONS.allocate(this.nd, this.address, length);
+ }
+
+ public NdAnnotation createAnnotation() {
+ return createAnnotationData().createAnnotation();
+ }
+
+ public NdTypeAnnotation createTypeAnnotation() {
+ return createAnnotationData().createTypeAnnotation();
+ }
+
+ public void allocateAnnotations(int length) {
+ if (length > 0) {
+ createAnnotationData().allocateAnnotations(length);
+ }
+ }
+
+ public void allocateTypeAnnotations(int length) {
+ if (length > 0) {
+ createAnnotationData().allocateTypeAnnotations(length);
+ }
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodAnnotationData.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodAnnotationData.java
index d7d62a32f2..a06518a635 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodAnnotationData.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodAnnotationData.java
@@ -14,8 +14,8 @@ import java.util.List;
import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.NdNode;
+import org.eclipse.jdt.internal.core.nd.field.FieldList;
import org.eclipse.jdt.internal.core.nd.field.FieldLong;
-import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany;
import org.eclipse.jdt.internal.core.nd.field.FieldOneToOne;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
@@ -26,8 +26,8 @@ import org.eclipse.jdt.internal.core.nd.field.StructDef;
public class NdMethodAnnotationData extends NdNode {
public static final FieldOneToOne<NdMethod> METHOD;
public static final FieldLong TAG_BITS;
- public static final FieldOneToMany<NdAnnotationInMethod> ANNOTATIONS;
- public static final FieldOneToMany<NdTypeAnnotationInMethod> TYPE_ANNOTATIONS;
+ public static final FieldList<NdAnnotation> ANNOTATIONS;
+ public static final FieldList<NdTypeAnnotation> TYPE_ANNOTATIONS;
@SuppressWarnings("hiding")
public static final StructDef<NdMethodAnnotationData> type;
@@ -36,8 +36,8 @@ public class NdMethodAnnotationData extends NdNode {
type = StructDef.create(NdMethodAnnotationData.class, NdNode.type);
METHOD = FieldOneToOne.createOwner(type, NdMethod.type, NdMethod.ANNOTATION_DATA);
TAG_BITS = type.addLong();
- ANNOTATIONS = FieldOneToMany.create(type, NdAnnotationInMethod.OWNER);
- TYPE_ANNOTATIONS = FieldOneToMany.create(type, NdTypeAnnotationInMethod.OWNER);
+ ANNOTATIONS = FieldList.create(type, NdAnnotation.type);
+ TYPE_ANNOTATIONS = FieldList.create(type, NdTypeAnnotation.type);
type.done();
}
@@ -59,11 +59,27 @@ public class NdMethodAnnotationData extends NdNode {
return TAG_BITS.get(getNd(), this.address);
}
- public List<NdTypeAnnotationInMethod> getTypeAnnotations() {
+ public List<NdTypeAnnotation> getTypeAnnotations() {
return TYPE_ANNOTATIONS.asList(getNd(), this.address);
}
- public List<NdAnnotationInMethod> getAnnotations() {
+ public List<NdAnnotation> getAnnotations() {
return ANNOTATIONS.asList(getNd(), this.address);
}
+
+ public NdAnnotation createAnnotation() {
+ return ANNOTATIONS.append(getNd(), getAddress());
+ }
+
+ public void allocateAnnotations(int length) {
+ ANNOTATIONS.allocate(getNd(), getAddress(), length);
+ }
+
+ public NdTypeAnnotation createTypeAnnotation() {
+ return TYPE_ANNOTATIONS.append(getNd(), getAddress());
+ }
+
+ public void allocateTypeAnnotations(int length) {
+ TYPE_ANNOTATIONS.allocate(getNd(), getAddress(), length);
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodException.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodException.java
index 4c7cfe5a26..a90d63d9c3 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodException.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodException.java
@@ -11,21 +11,19 @@
package org.eclipse.jdt.internal.core.nd.java;
import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.NdNode;
+import org.eclipse.jdt.internal.core.nd.NdStruct;
import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
-public class NdMethodException extends NdNode {
+public class NdMethodException extends NdStruct {
- public static final FieldManyToOne<NdMethod> PARENT;
public static final FieldManyToOne<NdTypeSignature> EXCEPTION_TYPE;
@SuppressWarnings("hiding")
public static StructDef<NdMethodException> type;
static {
- type = StructDef.create(NdMethodException.class, NdNode.type);
- PARENT = FieldManyToOne.createOwner(type, NdMethod.EXCEPTIONS);
+ type = StructDef.create(NdMethodException.class);
EXCEPTION_TYPE = FieldManyToOne.create(type, NdTypeSignature.USED_AS_EXCEPTION);
type.done();
}
@@ -34,21 +32,14 @@ public class NdMethodException extends NdNode {
super(nd, address);
}
- public NdMethodException(NdMethod method, NdTypeSignature createTypeSignature) {
- super(method.getNd());
-
- PARENT.put(getNd(), this.address, method);
- EXCEPTION_TYPE.put(getNd(), this.address, createTypeSignature);
+ public void setExceptionType(NdTypeSignature signature) {
+ EXCEPTION_TYPE.put(getNd(), this.address, signature);
}
public NdTypeSignature getExceptionType() {
return EXCEPTION_TYPE.get(getNd(), this.address);
}
- public NdMethod getParent() {
- return PARENT.get(getNd(), this.address);
- }
-
public String toString() {
try {
return getExceptionType().toString();
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodParameter.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodParameter.java
index bdcd8324df..47d5df26de 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodParameter.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdMethodParameter.java
@@ -13,20 +13,19 @@ package org.eclipse.jdt.internal.core.nd.java;
import java.util.List;
import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.NdNode;
+import org.eclipse.jdt.internal.core.nd.NdStruct;
import org.eclipse.jdt.internal.core.nd.db.IString;
import org.eclipse.jdt.internal.core.nd.field.FieldByte;
+import org.eclipse.jdt.internal.core.nd.field.FieldList;
import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
-import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany;
import org.eclipse.jdt.internal.core.nd.field.FieldString;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
-public class NdMethodParameter extends NdNode {
- public static final FieldManyToOne<NdMethod> PARENT;
+public class NdMethodParameter extends NdStruct {
public static final FieldManyToOne<NdTypeSignature> ARGUMENT_TYPE;
public static final FieldString NAME;
- public static final FieldOneToMany<NdAnnotationInMethodParameter> ANNOTATIONS;
+ public static final FieldList<NdAnnotation> ANNOTATIONS;
public static final FieldByte FLAGS;
private static final byte FLG_COMPILER_DEFINED = 0x01;
@@ -35,11 +34,10 @@ public class NdMethodParameter extends NdNode {
public static StructDef<NdMethodParameter> type;
static {
- type = StructDef.create(NdMethodParameter.class, NdNode.type);
- PARENT = FieldManyToOne.create(type, NdMethod.PARAMETERS);
+ type = StructDef.create(NdMethodParameter.class);
ARGUMENT_TYPE = FieldManyToOne.create(type, NdTypeSignature.USED_AS_METHOD_ARGUMENT);
NAME = type.addString();
- ANNOTATIONS = FieldOneToMany.create(type, NdAnnotationInMethodParameter.OWNER);
+ ANNOTATIONS = FieldList.create(type, NdAnnotation.type);
FLAGS = type.addByte();
type.done();
}
@@ -48,10 +46,7 @@ public class NdMethodParameter extends NdNode {
super(nd, address);
}
- public NdMethodParameter(NdMethod parent, NdTypeSignature argumentType) {
- super(parent.getNd());
-
- PARENT.put(getNd(), this.address, parent);
+ public void setType(NdTypeSignature argumentType) {
ARGUMENT_TYPE.put(getNd(), this.address, argumentType);
}
@@ -67,7 +62,7 @@ public class NdMethodParameter extends NdNode {
return NAME.get(getNd(), this.address);
}
- public List<NdAnnotationInMethodParameter> getAnnotations() {
+ public List<NdAnnotation> getAnnotations() {
return ANNOTATIONS.asList(getNd(), this.address);
}
@@ -102,4 +97,12 @@ public class NdMethodParameter extends NdNode {
return super.toString();
}
}
+
+ public NdAnnotation createAnnotation() {
+ return ANNOTATIONS.append(getNd(), getAddress());
+ }
+
+ public void allocateAnnotations(int length) {
+ ANNOTATIONS.allocate(getNd(), getAddress(), length);
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdResourceFile.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdResourceFile.java
index 8a81f10353..9c8e979795 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdResourceFile.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdResourceFile.java
@@ -22,6 +22,7 @@ import org.eclipse.jdt.internal.core.nd.NdNode;
import org.eclipse.jdt.internal.core.nd.db.Database;
import org.eclipse.jdt.internal.core.nd.db.IString;
import org.eclipse.jdt.internal.core.nd.db.IndexException;
+import org.eclipse.jdt.internal.core.nd.field.FieldList;
import org.eclipse.jdt.internal.core.nd.field.FieldLong;
import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany;
import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany.Visitor;
@@ -45,7 +46,7 @@ public class NdResourceFile extends NdNode {
public static final FieldOneToMany<NdWorkspaceLocation> WORKSPACE_MAPPINGS;
public static final FieldString JAVA_ROOT;
public static final FieldLong JDK_LEVEL;
- public static final FieldOneToMany<NdZipEntry> ZIP_ENTRIES;
+ public static final FieldList<NdZipEntry> ZIP_ENTRIES;
public static final FieldString MANIFEST_CONTENT;
public static final FieldShort FILE_FLAGS;
@@ -68,7 +69,7 @@ public class NdResourceFile extends NdNode {
WORKSPACE_MAPPINGS = FieldOneToMany.create(type, NdWorkspaceLocation.RESOURCE);
JAVA_ROOT = type.addString();
JDK_LEVEL = type.addLong();
- ZIP_ENTRIES = FieldOneToMany.create(type, NdZipEntry.JAR_FILE);
+ ZIP_ENTRIES = FieldList.create(type, NdZipEntry.type, 1);
MANIFEST_CONTENT = type.addString();
FILE_FLAGS = type.addShort();
@@ -148,16 +149,16 @@ public class NdResourceFile extends NdNode {
*/
public boolean isInIndex() {
try {
- Nd nd = getNd();
// In the common case where the resource file was deleted and the memory hasn't yet been reused,
// this will fail.
- if (!nd.isValidAddress(this.address) || NODE_TYPE.get(nd, this.address) != nd.getNodeType(getClass())) {
+ if (!this.nd.isValidAddress(this.address)
+ || NODE_TYPE.get(this.nd, this.address) != this.nd.getNodeType(getClass())) {
return false;
}
char[] filename = FILENAME.get(getNd(), this.address).getChars();
- NdResourceFile result = JavaIndex.FILES.findBest(nd, Database.DATA_AREA_OFFSET,
+ NdResourceFile result = JavaIndex.FILES.findBest(this.nd, Database.DATA_AREA_OFFSET,
SearchCriteria.create(filename), new IResultRank() {
@Override
public long getRank(Nd testNd, long testAddress) {
@@ -327,4 +328,14 @@ public class NdResourceFile extends NdNode {
return super.toString();
}
}
+
+ public void allocateZipEntries(int expectedNumberOfZipEntries) {
+ ZIP_ENTRIES.allocate(this.nd, this.address, expectedNumberOfZipEntries);
+ }
+
+ public NdZipEntry addZipEntry(String fileName) {
+ NdZipEntry result = ZIP_ENTRIES.append(getNd(), getAddress());
+ result.setFilename(fileName);
+ return result;
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdType.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdType.java
index d83f37a4f1..2594136c49 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdType.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdType.java
@@ -12,11 +12,10 @@ package org.eclipse.jdt.internal.core.nd.java;
import java.util.List;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.internal.core.nd.INdVisitor;
import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.db.IString;
import org.eclipse.jdt.internal.core.nd.field.FieldByte;
+import org.eclipse.jdt.internal.core.nd.field.FieldList;
import org.eclipse.jdt.internal.core.nd.field.FieldLong;
import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany;
@@ -32,8 +31,9 @@ public class NdType extends NdBinding {
public static final FieldManyToOne<NdTypeId> DECLARING_TYPE;
public static final FieldManyToOne<NdMethodId> DECLARING_METHOD;
public static final FieldOneToMany<NdMethod> METHODS;
- public static final FieldOneToMany<NdTypeAnnotationInType> TYPE_ANNOTATIONS;
- public static final FieldOneToMany<NdAnnotationInType> ANNOTATIONS;
+ public static final FieldList<NdTypeAnnotation> TYPE_ANNOTATIONS;
+ public static final FieldList<NdAnnotation> ANNOTATIONS;
+ public static final FieldList<NdVariable> VARIABLES;
public static final FieldString MISSING_TYPE_NAMES;
public static final FieldString SOURCE_FILE_NAME;
public static final FieldString INNER_CLASS_SOURCE_NAME;
@@ -58,8 +58,9 @@ public class NdType extends NdBinding {
SUPERCLASS = FieldManyToOne.create(type, NdTypeSignature.SUBCLASSES);
DECLARING_METHOD = FieldManyToOne.create(type, NdMethodId.DECLARED_TYPES);
METHODS = FieldOneToMany.create(type, NdMethod.PARENT, 6);
- TYPE_ANNOTATIONS = FieldOneToMany.create(type, NdTypeAnnotationInType.OWNER);
- ANNOTATIONS = FieldOneToMany.create(type, NdAnnotationInType.OWNER);
+ TYPE_ANNOTATIONS = FieldList.create(type, NdTypeAnnotation.type);
+ ANNOTATIONS = FieldList.create(type, NdAnnotation.type);
+ VARIABLES = FieldList.create(type, NdVariable.type);
MISSING_TYPE_NAMES = type.addString();
SOURCE_FILE_NAME = type.addString();
INNER_CLASS_SOURCE_NAME = type.addString();
@@ -84,13 +85,6 @@ public class NdType extends NdBinding {
FILE.put(nd, this.address, resource);
}
- /**
- * Called to populate the cache for the bindings in the class scope.
- */
- public void acceptUncached(INdVisitor visitor) throws CoreException {
- super.accept(visitor);
- }
-
public NdTypeId getTypeId() {
return TYPENAME.get(getNd(), this.address);
}
@@ -221,6 +215,10 @@ public class NdType extends NdBinding {
return JavaNames.simpleNameToSourceName(simpleName);
}
+ public List<NdVariable> getVariables() {
+ return VARIABLES.asList(getNd(), this.address);
+ }
+
public NdMethodId getDeclaringMethod() {
return DECLARING_METHOD.get(getNd(), this.address);
}
@@ -230,14 +228,22 @@ public class NdType extends NdBinding {
return TYPE_PARAMETERS.asList(getNd(), this.address);
}
- public List<NdTypeAnnotationInType> getTypeAnnotations() {
+ public List<NdTypeAnnotation> getTypeAnnotations() {
return TYPE_ANNOTATIONS.asList(getNd(), this.address);
}
- public List<NdAnnotationInType> getAnnotations() {
+ public List<NdAnnotation> getAnnotations() {
return ANNOTATIONS.asList(getNd(), this.address);
}
+ public NdAnnotation createAnnotation() {
+ return ANNOTATIONS.append(getNd(), getAddress());
+ }
+
+ public void allocateAnnotations(int length) {
+ ANNOTATIONS.allocate(getNd(), getAddress(), length);
+ }
+
public List<NdMethod> getMethods() {
return METHODS.asList(getNd(), this.address);
}
@@ -275,4 +281,20 @@ public class NdType extends NdBinding {
}
return descriptorFromClass;
}
+
+ public NdTypeAnnotation createTypeAnnotation() {
+ return TYPE_ANNOTATIONS.append(getNd(), getAddress());
+ }
+
+ public void allocateTypeAnnotations(int length) {
+ TYPE_ANNOTATIONS.allocate(getNd(), getAddress(), length);
+ }
+
+ public NdVariable createVariable() {
+ return VARIABLES.append(getNd(), getAddress());
+ }
+
+ public void allocateVariables(int length) {
+ VARIABLES.allocate(getNd(), getAddress(), length);
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotation.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotation.java
index e9bfa4a4d6..b6c0908eb1 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotation.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotation.java
@@ -11,13 +11,14 @@
package org.eclipse.jdt.internal.core.nd.java;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
+import org.eclipse.jdt.internal.core.nd.IDestructable;
import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.db.Database;
import org.eclipse.jdt.internal.core.nd.field.FieldByte;
import org.eclipse.jdt.internal.core.nd.field.FieldPointer;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
-public class NdTypeAnnotation extends NdAnnotation {
+public class NdTypeAnnotation extends NdAnnotation implements IDestructable {
public static final FieldByte TARGET_TYPE;
public static final FieldByte TARGET_ARG0;
public static final FieldByte TARGET_ARG1;
@@ -43,18 +44,13 @@ public class NdTypeAnnotation extends NdAnnotation {
super(nd, address);
}
- public NdTypeAnnotation(Nd nd) {
- super(nd);
- }
-
public void setPath(byte[] path) {
freePath();
- Nd nd = getNd();
- PATH_LENGTH.put(nd, this.address, (byte)path.length);
+ PATH_LENGTH.put(this.nd, this.address, (byte) path.length);
if (path.length > 0) {
- long pathArray = nd.getDB().malloc(path.length, Database.POOL_MISC);
- PATH.put(nd, this.address, pathArray);
- nd.getDB().putBytes(pathArray, path, path.length);
+ long pathArray = this.nd.getDB().malloc(path.length, Database.POOL_MISC);
+ PATH.put(this.nd, this.address, pathArray);
+ this.nd.getDB().putBytes(pathArray, path, path.length);
}
}
@@ -111,12 +107,10 @@ public class NdTypeAnnotation extends NdAnnotation {
@Override
public void destruct() {
freePath();
- super.destruct();
}
private void freePath() {
- Nd nd = getNd();
- long pathPointer = PATH.get(nd, this.address);
- nd.getDB().free(pathPointer, Database.POOL_MISC);
+ long pathPointer = PATH.get(this.nd, this.address);
+ this.nd.getDB().free(pathPointer, Database.POOL_MISC);
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInMethod.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInMethod.java
deleted file mode 100644
index 06dcce393a..0000000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInMethod.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2016 Google, Inc and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.nd.java;
-
-import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
-import org.eclipse.jdt.internal.core.nd.field.StructDef;
-
-public class NdTypeAnnotationInMethod extends NdTypeAnnotation {
- public static final FieldManyToOne<NdMethodAnnotationData> OWNER;
-
- @SuppressWarnings("hiding")
- public static final StructDef<NdTypeAnnotationInMethod> type;
-
- static {
- type = StructDef.create(NdTypeAnnotationInMethod.class, NdTypeAnnotation.type);
- OWNER = FieldManyToOne.createOwner(type, NdMethodAnnotationData.TYPE_ANNOTATIONS);
- type.done();
- }
-
- public NdTypeAnnotationInMethod(Nd nd, long address) {
- super(nd, address);
- }
-
- public NdTypeAnnotationInMethod(Nd nd, NdMethod method) {
- super(nd);
-
- OWNER.put(getNd(), this.address, method.createAnnotationData());
- }
-
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInType.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInType.java
deleted file mode 100644
index 7aff109084..0000000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInType.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2016 Google, Inc and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.nd.java;
-
-import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
-import org.eclipse.jdt.internal.core.nd.field.StructDef;
-
-public class NdTypeAnnotationInType extends NdTypeAnnotation {
- public static final FieldManyToOne<NdType> OWNER;
-
- @SuppressWarnings("hiding")
- public static final StructDef<NdTypeAnnotationInType> type;
-
- static {
- type = StructDef.create(NdTypeAnnotationInType.class, NdTypeAnnotation.type);
- OWNER = FieldManyToOne.createOwner(type, NdType.TYPE_ANNOTATIONS);
- type.done();
- }
-
- public NdTypeAnnotationInType(Nd nd, long address) {
- super(nd, address);
- }
-
- public NdTypeAnnotationInType(Nd nd, NdType type) {
- super(nd);
-
- OWNER.put(getNd(), this.address, type);
- }
-
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInVariable.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInVariable.java
deleted file mode 100644
index eb591fe06e..0000000000
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeAnnotationInVariable.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2016 Google, Inc and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Stefan Xenos (Google) - Initial implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.core.nd.java;
-
-import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
-import org.eclipse.jdt.internal.core.nd.field.StructDef;
-
-public class NdTypeAnnotationInVariable extends NdTypeAnnotation {
- public static final FieldManyToOne<NdVariable> OWNER;
-
- @SuppressWarnings("hiding")
- public static final StructDef<NdTypeAnnotationInVariable> type;
-
- static {
- type = StructDef.create(NdTypeAnnotationInVariable.class, NdTypeAnnotation.type);
- OWNER = FieldManyToOne.createOwner(type, NdVariable.TYPE_ANNOTATIONS);
- type.done();
- }
-
- public NdTypeAnnotationInVariable(Nd nd, long address) {
- super(nd, address);
- }
-
- public NdTypeAnnotationInVariable(Nd nd, NdVariable variable) {
- super(nd);
-
- OWNER.put(getNd(), this.address, variable);
- }
-
-}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeBound.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeBound.java
index c6c827eeef..1a5e0ef395 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeBound.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeBound.java
@@ -11,7 +11,7 @@
package org.eclipse.jdt.internal.core.nd.java;
import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.NdNode;
+import org.eclipse.jdt.internal.core.nd.NdStruct;
import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
@@ -20,16 +20,14 @@ import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
* Represents the bound on a generic parameter (a ClassBound or InterfaceBound in
* the sense of the Java VM spec Java SE 8 Edition, section 4.7.9.1).
*/
-public class NdTypeBound extends NdNode {
- public static final FieldManyToOne<NdTypeParameter> PARENT;
+public class NdTypeBound extends NdStruct {
public static final FieldManyToOne<NdTypeSignature> TYPE;
@SuppressWarnings("hiding")
public static final StructDef<NdTypeBound> type;
static {
- type = StructDef.create(NdTypeBound.class, NdNode.type);
- PARENT = FieldManyToOne.createOwner(type, NdTypeParameter.BOUNDS);
+ type = StructDef.create(NdTypeBound.class, NdStruct.type);
TYPE = FieldManyToOne.create(type, NdTypeSignature.USED_AS_TYPE_BOUND);
type.done();
@@ -39,17 +37,10 @@ public class NdTypeBound extends NdNode {
super(nd, address);
}
- public NdTypeBound(NdTypeParameter parent, NdTypeSignature signature) {
- super(parent.getNd());
-
- PARENT.put(getNd(), this.address, parent);
+ public void setType(NdTypeSignature signature) {
TYPE.put(getNd(), this.address, signature);
}
- public NdTypeParameter getParent() {
- return PARENT.get(getNd(), this.address);
- }
-
public NdTypeSignature getType() {
return TYPE.get(getNd(), this.address);
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeParameter.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeParameter.java
index fda4676b18..8809b841ad 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeParameter.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdTypeParameter.java
@@ -13,10 +13,9 @@ package org.eclipse.jdt.internal.core.nd.java;
import java.util.List;
import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.NdNode;
+import org.eclipse.jdt.internal.core.nd.NdStruct;
import org.eclipse.jdt.internal.core.nd.field.FieldByte;
-import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
-import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany;
+import org.eclipse.jdt.internal.core.nd.field.FieldList;
import org.eclipse.jdt.internal.core.nd.field.FieldString;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
@@ -24,10 +23,9 @@ import org.eclipse.jdt.internal.core.util.CharArrayBuffer;
/**
* Represents a TypeParameter, as described in Section 4.7.9.1 of the java VM specification, Java SE 8 edititon.
*/
-public class NdTypeParameter extends NdNode {
- public static final FieldManyToOne<NdBinding> PARENT;
+public class NdTypeParameter extends NdStruct {
public static final FieldString IDENTIFIER;
- public static final FieldOneToMany<NdTypeBound> BOUNDS;
+ public static final FieldList<NdTypeBound> BOUNDS;
public static final FieldByte TYPE_PARAMETER_FLAGS;
public static final byte FLG_FIRST_BOUND_IS_A_CLASS = 0x01;
@@ -36,10 +34,9 @@ public class NdTypeParameter extends NdNode {
public static final StructDef<NdTypeParameter> type;
static {
- type = StructDef.create(NdTypeParameter.class, NdNode.type);
- PARENT = FieldManyToOne.createOwner(type, NdBinding.TYPE_PARAMETERS);
+ type = StructDef.create(NdTypeParameter.class, NdStruct.type);
IDENTIFIER = type.addString();
- BOUNDS = FieldOneToMany.create(type, NdTypeBound.PARENT);
+ BOUNDS = FieldList.create(type, NdTypeBound.type);
TYPE_PARAMETER_FLAGS = type.addByte();
type.done();
@@ -49,10 +46,7 @@ public class NdTypeParameter extends NdNode {
super(nd, address);
}
- public NdTypeParameter(NdBinding parent, char[] identifier) {
- super(parent.getNd());
-
- PARENT.put(getNd(), this.address, parent);
+ public void setIdentifier(char[] identifier) {
IDENTIFIER.put(getNd(), this.address, identifier);
}
@@ -108,4 +102,12 @@ public class NdTypeParameter extends NdNode {
buffer.append('>');
}
}
+
+ public void createBound(NdTypeSignature boundSignature) {
+ BOUNDS.append(getNd(), getAddress()).setType(boundSignature);
+ }
+
+ public void allocateBounds(int numBounds) {
+ BOUNDS.allocate(getNd(), getAddress(), numBounds);
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdVariable.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdVariable.java
index 0ab3beefc0..1006637b2c 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdVariable.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdVariable.java
@@ -16,9 +16,9 @@ import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.db.IString;
import org.eclipse.jdt.internal.core.nd.field.FieldByte;
import org.eclipse.jdt.internal.core.nd.field.FieldInt;
+import org.eclipse.jdt.internal.core.nd.field.FieldList;
import org.eclipse.jdt.internal.core.nd.field.FieldLong;
import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
-import org.eclipse.jdt.internal.core.nd.field.FieldOneToMany;
import org.eclipse.jdt.internal.core.nd.field.FieldOneToOne;
import org.eclipse.jdt.internal.core.nd.field.FieldString;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
@@ -27,13 +27,12 @@ public class NdVariable extends NdBinding {
public static final FieldManyToOne<NdTypeSignature> TYPE;
public static final FieldInt VARIABLE_ID;
public static final FieldManyToOne<NdMethod> DECLARING_METHOD;
- public static final FieldManyToOne<NdBinding> PARENT;
public static final FieldString NAME;
public static final FieldOneToOne<NdConstant> CONSTANT;
public static final FieldLong TAG_BITS;
public static final FieldByte VARIABLE_FLAGS;
- public static final FieldOneToMany<NdAnnotationInVariable> ANNOTATIONS;
- public static final FieldOneToMany<NdTypeAnnotationInVariable> TYPE_ANNOTATIONS;
+ public static final FieldList<NdAnnotation> ANNOTATIONS;
+ public static final FieldList<NdTypeAnnotation> TYPE_ANNOTATIONS;
@SuppressWarnings("hiding")
public static StructDef<NdVariable> type;
@@ -45,13 +44,12 @@ public class NdVariable extends NdBinding {
TYPE = FieldManyToOne.create(type, NdTypeSignature.VARIABLES_OF_TYPE);
VARIABLE_ID = type.addInt();
DECLARING_METHOD = FieldManyToOne.create(type, NdMethod.DECLARED_VARIABLES);
- PARENT = FieldManyToOne.createOwner(type, NdBinding.VARIABLES);
NAME = type.addString();
CONSTANT = FieldOneToOne.create(type, NdConstant.type, NdConstant.PARENT_VARIABLE);
TAG_BITS = type.addLong();
VARIABLE_FLAGS = type.addByte();
- ANNOTATIONS = FieldOneToMany.create(type, NdAnnotationInVariable.OWNER);
- TYPE_ANNOTATIONS = FieldOneToMany.create(type, NdTypeAnnotationInVariable.OWNER);
+ ANNOTATIONS = FieldList.create(type, NdAnnotation.type);
+ TYPE_ANNOTATIONS = FieldList.create(type, NdTypeAnnotation.type);
type.done();
}
@@ -59,12 +57,6 @@ public class NdVariable extends NdBinding {
super(nd, bindingRecord);
}
- public NdVariable(NdBinding parent) {
- super(parent.getNd());
-
- PARENT.put(getNd(), this.address, parent);
- }
-
public boolean hasVariableFlag(int toTest) {
return (VARIABLE_FLAGS.get(getNd(), this.address) & toTest) != 0;
}
@@ -106,14 +98,22 @@ public class NdVariable extends NdBinding {
TAG_BITS.put(getNd(), this.address, tagBits);
}
- public List<NdTypeAnnotationInVariable> getTypeAnnotations() {
+ public List<NdTypeAnnotation> getTypeAnnotations() {
return TYPE_ANNOTATIONS.asList(getNd(), this.address);
}
- public List<NdAnnotationInVariable> getAnnotations() {
+ public List<NdAnnotation> getAnnotations() {
return ANNOTATIONS.asList(getNd(), this.address);
}
+ public NdAnnotation createAnnotation() {
+ return ANNOTATIONS.append(this.getNd(), this.getAddress());
+ }
+
+ public void allocateAnnotations(int length) {
+ ANNOTATIONS.allocate(getNd(), getAddress(), length);
+ }
+
public String toString() {
try {
StringBuilder result = new StringBuilder();
@@ -138,4 +138,12 @@ public class NdVariable extends NdBinding {
return super.toString();
}
}
+
+ public NdTypeAnnotation createTypeAnnotation() {
+ return TYPE_ANNOTATIONS.append(getNd(), getAddress());
+ }
+
+ public void allocateTypeAnnotations(int length) {
+ TYPE_ANNOTATIONS.allocate(getNd(), getAddress(), length);
+ }
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdZipEntry.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdZipEntry.java
index e0086ab193..4e4f82cf52 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdZipEntry.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/NdZipEntry.java
@@ -11,25 +11,22 @@
package org.eclipse.jdt.internal.core.nd.java;
import org.eclipse.jdt.internal.core.nd.Nd;
-import org.eclipse.jdt.internal.core.nd.NdNode;
+import org.eclipse.jdt.internal.core.nd.NdStruct;
import org.eclipse.jdt.internal.core.nd.db.IString;
-import org.eclipse.jdt.internal.core.nd.field.FieldManyToOne;
import org.eclipse.jdt.internal.core.nd.field.FieldString;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
/**
* Stores a (non-class) file within a .jar file.
*/
-public class NdZipEntry extends NdNode {
- public static final FieldManyToOne<NdResourceFile> JAR_FILE;
+public class NdZipEntry extends NdStruct {
public static final FieldString FILE_NAME;
@SuppressWarnings("hiding")
public static final StructDef<NdZipEntry> type;
static {
- type = StructDef.create(NdZipEntry.class, NdNode.type);
- JAR_FILE = FieldManyToOne.createOwner(type, NdResourceFile.ZIP_ENTRIES);
+ type = StructDef.create(NdZipEntry.class, NdStruct.type);
FILE_NAME = type.addString();
type.done();
@@ -39,14 +36,11 @@ public class NdZipEntry extends NdNode {
super(nd, address);
}
- public NdZipEntry(NdResourceFile nd, String path) {
- super(nd.getNd());
-
- JAR_FILE.put(nd.getNd(), getAddress(), nd);
- FILE_NAME.put(nd.getNd(), getAddress(), path);
+ public void setFilename(String filename) {
+ FILE_NAME.put(this.nd, this.address, filename);
}
public IString getFileName() {
- return FILE_NAME.get(getNd(), getAddress());
+ return FILE_NAME.get(this.nd, this.address);
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/util/MathUtils.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/util/MathUtils.java
new file mode 100644
index 0000000000..25c94e8084
--- /dev/null
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/util/MathUtils.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Google, Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stefan Xenos (Google) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.core.nd.util;
+
+public class MathUtils {
+ /**
+ * Rounds the one number up to the nearest multiple of another
+ *
+ * @param numberToRound
+ * number to round
+ * @param toMultipleOfThis the result will be divisible by this number
+ * @return the result will be the smallest multiple of toMultipleOfThis that is no smaller than numberToRound
+ */
+ public static int roundUpToNearestMultiple(int numberToRound, int toMultipleOfThis) {
+ return ((numberToRound + toMultipleOfThis - 1) / toMultipleOfThis) * toMultipleOfThis;
+ }
+
+ /**
+ * Rounds the one number up to the nearest multiple of another, where the second number is a power of two.
+ *
+ * @param numberToRound
+ * number to round
+ * @param aPowerOfTwo
+ * the result will be divisible by this
+ * @return the result will be the smallest multiple of aPowerOfTwo that is no smaller than numberToRound
+ */
+ public static int roundUpToNearestMultipleOfPowerOfTwo(int numberToRound, int aPowerOfTwo) {
+ return ((numberToRound + aPowerOfTwo - 1) & ~(aPowerOfTwo - 1));
+ }
+}

Back to the top