Bug 513704 - An NPE exceptions like CompilationUnit.buildStructure() started to appear

Change-Id: Ic32915622c3336fc8841f0e24160216af58d2cba
Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/core/dom/ASTParser.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/core/dom/ASTParser.java
index e87d045..385301f 100644
--- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/core/dom/ASTParser.java
+++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/core/dom/ASTParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2016 IBM Corporation and others.
+ * Copyright (c) 2004, 2017 IBM Corporation 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
@@ -29,6 +29,7 @@
 import org.eclipse.wst.jsdt.internal.compiler.parser.Scanner;
 import org.eclipse.wst.jsdt.internal.core.BasicCompilationUnit;
 import org.eclipse.wst.jsdt.internal.core.DefaultWorkingCopyOwner;
+import org.eclipse.wst.jsdt.internal.core.Logger;
 import org.eclipse.wst.jsdt.internal.core.PackageFragment;
 import org.eclipse.wst.jsdt.internal.core.util.RecordedParsingInformation;
 import org.eclipse.wst.jsdt.internal.core.util.Util;
@@ -675,6 +676,7 @@
 			}
 		} catch (Throwable e) {
 			e.printStackTrace();
+			Logger.logException(e);
 		} finally {
 	   	   // re-init defaults to allow reuse (and avoid leaking)
 	   	   initializeDefaults();
diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/core/dom/ObjectLiteralField.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/core/dom/ObjectLiteralField.java
index d10f0a9..684b1d5 100644
--- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/core/dom/ObjectLiteralField.java
+++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/core/dom/ObjectLiteralField.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 IBM Corporation 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
@@ -132,7 +132,7 @@
 			if (get) {
 				return getInitializer();
 			} else {
-				setInitializer((Expression) child);
+				setInitializer(child instanceof Expression ? (Expression) child : null);
 				return null;
 			}
 		}
diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/CompilationUnitStructureVisitor.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/CompilationUnitStructureVisitor.java
index 90198c4..1ddf5a7 100644
--- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/CompilationUnitStructureVisitor.java
+++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/CompilationUnitStructureVisitor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2016 Red Hat, Inc. 

+ * Copyright (c) 2016, 2017 Red Hat, Inc. 

  * 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

@@ -319,7 +319,9 @@
 			this.newElements.put(importContainer, this.importContainerInfo);

 		}

 

-		final SimpleName localName = module.getLocal();

+		final SimpleName localName = (module.getLocal() != null ? 

+					module.getLocal() : 

+						module.getDiscoverableName());

 		StringBuilder nameString = new StringBuilder(parent.getSource().getLiteralValue());

 		nameString.append(" as ");

 		nameString.append(localName.getIdentifier());

@@ -454,68 +456,72 @@
 		}

 		return false;

 	}

-	

+

 	public boolean visit(VariableDeclarationFragment node){

 		JavaElementInfo parentInfo = this.infoStack.peek();

 		JavaElement parentHandle= this.handleStack.peek();

-		String fieldName = JavaModelManager.getJavaModelManager().intern(

-					new String(node.getName().getIdentifier()));

-		SourceField handle = new SourceField(parentHandle, fieldName);

-		resolveDuplicates(handle);

-		

-		

-		SourceFieldElementInfo info = new SourceFieldElementInfo();

-		info.setNameSourceStart(node.getName().getStartPosition());

-		info.setNameSourceEnd(node.getName().getStartPosition() + node.getName().getLength()-1);

-		info.setSourceRangeStart(node.getStartPosition());

-		

-		if(node.getParent().getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT &&

-					node.getParent().getStructuralProperty(VariableDeclarationStatement.KIND_PROPERTY)

-					== VariableKind.CONST){

-			info.flags |= ClassFileConstants.AccStatic | ClassFileConstants.AccFinal;

-		}

-		

-		if (node.getInitializer() != null) {

-			int initializerType = node.getInitializer().getNodeType();

-			String typeString = null;

-			switch (initializerType) {

-				case ASTNode.BOOLEAN_LITERAL :

-					typeString = Signature.createTypeSignature("boolean", false);

-					break;

-				case ASTNode.NUMBER_LITERAL :

-					typeString = "Number";

-					break;

-				case ASTNode.STRING_LITERAL :

-					typeString = "String";

-					break;

-				case ASTNode.OBJECT_LITERAL :

-					typeString = "{}";

-					break;

-				default :

-					break;

+		if (node.getPattern().getNodeType() == ASTNode.SIMPLE_NAME) {

+			String fieldName = JavaModelManager.getJavaModelManager().intern(

+						String.valueOf(node.getName().getIdentifier()));

+			SourceField handle = new SourceField(parentHandle, fieldName);

+			resolveDuplicates(handle);

+			

+			

+			SourceFieldElementInfo info = new SourceFieldElementInfo();

+			info.setNameSourceStart(node.getName().getStartPosition());

+			info.setNameSourceEnd(node.getName().getStartPosition() + node.getName().getLength()-1);

+			info.setSourceRangeStart(node.getStartPosition());

+			

+			if(node.getParent().getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT &&

+						node.getParent().getStructuralProperty(VariableDeclarationStatement.KIND_PROPERTY)

+						== VariableKind.CONST){

+				info.flags |= ClassFileConstants.AccStatic | ClassFileConstants.AccFinal;

 			}

-			if (typeString != null) {

-				char[] typeName = JavaModelManager.getJavaModelManager().intern(typeString.toCharArray());

-				info.setTypeName(typeName);

+			

+			if (node.getInitializer() != null) {

+				int initializerType = node.getInitializer().getNodeType();

+				String typeString = null;

+				switch (initializerType) {

+					case ASTNode.BOOLEAN_LITERAL :

+						typeString = Signature.createTypeSignature("boolean", false);

+						break;

+					case ASTNode.NUMBER_LITERAL :

+						typeString = "Number";

+						break;

+					case ASTNode.STRING_LITERAL :

+						typeString = "String";

+						break;

+					case ASTNode.OBJECT_LITERAL :

+						typeString = "{}";

+						break;

+					default :

+						break;

+				}

+				if (typeString != null) {

+					char[] typeName = JavaModelManager.getJavaModelManager().intern(typeString.toCharArray());

+					info.setTypeName(typeName);

+				}

 			}

-		}

-		

-		addToChildren(parentInfo, handle);

-		this.newElements.put(handle, info);

-		this.infoStack.push(info);

-		this.handleStack.push(handle);

-		if(node.getInitializer() != null ){

-			node.getInitializer().accept(this);

+			

+			addToChildren(parentInfo, handle);

+			this.newElements.put(handle, info);

+			this.infoStack.push(info);

+			this.handleStack.push(handle);

+			if(node.getInitializer() != null ){

+				node.getInitializer().accept(this);

+			}

 		}

 		return false;

 	}

 	

 	public void endVisit(VariableDeclarationFragment node){

-		SourceFieldElementInfo info = (SourceFieldElementInfo) this.infoStack.pop();

-		info.setSourceRangeEnd(node.getStartPosition() + node.getLength()-1);

-		setChildren(info);

-		

-		this.handleStack.pop();

+		if (node.getPattern().getNodeType() == ASTNode.SIMPLE_NAME) {

+			SourceFieldElementInfo info = (SourceFieldElementInfo) this.infoStack.pop();

+			info.setSourceRangeEnd(node.getStartPosition() + node.getLength()-1);

+			setChildren(info);

+			

+			this.handleStack.pop();

+		}

 	}

 	

 	public void endVisit(JavaScriptUnit node){

diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/dom/binding/ScopeDeclarationScanner.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/dom/binding/ScopeDeclarationScanner.java
index 5a0c4f4..1946d20 100644
--- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/dom/binding/ScopeDeclarationScanner.java
+++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/dom/binding/ScopeDeclarationScanner.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016 Eugene Melekhov and others.
+ * Copyright (c) 2016, 2017 Eugene Melekhov 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
@@ -92,7 +92,9 @@
 			switch (n.getNodeType()) {
 				case ASTNode.FUNCTION_EXPRESSION : {
 					FunctionDeclaration fd = ((FunctionExpression) n).getMethod();
-					SimpleName fNameNode = ((SimpleName) fd.getMethodName());
+					SimpleName fNameNode = (fd.getMethodName() instanceof SimpleName ? 
+								(SimpleName) fd.getMethodName() :
+									null);
 					if (fNameNode != null) {
 						declareFunction(fNameNode);
 					}
diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/indexing/ASTIndexerVisitor.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/indexing/ASTIndexerVisitor.java
index d940513..e00213a 100644
--- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/indexing/ASTIndexerVisitor.java
+++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/indexing/ASTIndexerVisitor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
-* Copyright (c) 2016 Red Hat, Inc.
+* Copyright (c) 2016, 2017 Red Hat, Inc.
 * 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
@@ -198,7 +198,7 @@
 		String name;
 		if (node.getName() != null) {
 			name = node.getName().getIdentifier();
-		} else if (node.getExpression().getNodeType() == ASTNode.FIELD_ACCESS) {
+		} else if (node.getExpression() != null && node.getExpression().getNodeType() == ASTNode.FIELD_ACCESS) {
 			name = ((FieldAccess) node.getExpression()).getName().getIdentifier();
 		} else {
 			// Can't index an anonymous function.
diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/indexing/SourceIndexer.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/indexing/SourceIndexer.java
index 83140a8..62a4857 100644
--- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/indexing/SourceIndexer.java
+++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/search/indexing/SourceIndexer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 IBM Corporation 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
@@ -91,11 +91,17 @@
 		// file save. For large projects this can be a significant performance impediment.
 		try {
 			ASTNode root = parser.createAST(null);
-			root.accept(visitor);
+			if (root != null) {
+				root.accept(visitor);
+			} else {
+				Util.verbose("AST couldn't be created during indexing file:  " + this.document.getPath()); //$NON-NLS-1$
+			}
 		} catch (ClassCastException e) {
+			e.printStackTrace();
 			Util.verbose("ClassCastException during indexing -- " + e.getMessage() //$NON-NLS-1$
 						+ "\n\t in file:  " + this.document.getPath()); //$NON-NLS-1$
 		} catch (IllegalArgumentException e) {
+			e.printStackTrace();
 			Util.verbose("IllegalArgumentException during indexing -- " + e.getMessage() //$NON-NLS-1$
 						+ "\n\t in file:  " + this.document.getPath()); //$NON-NLS-1$
 		}
diff --git a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/validation/JavaScriptValidator.java b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/validation/JavaScriptValidator.java
index 21ebf83..225eef7 100644
--- a/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/validation/JavaScriptValidator.java
+++ b/bundles/org.eclipse.wst.jsdt.core/src/org/eclipse/wst/jsdt/internal/core/validation/JavaScriptValidator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016 IBM Corporation and others.
+ * Copyright (c) 2016, 2017 IBM Corporation 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
@@ -23,6 +23,7 @@
 import org.eclipse.wst.jsdt.core.dom.JavaScriptUnit;
 import org.eclipse.wst.jsdt.internal.compiler.env.INameEnvironment;
 import org.eclipse.wst.jsdt.internal.core.JavaProject;
+import org.eclipse.wst.jsdt.internal.core.Logger;
 import org.eclipse.wst.jsdt.internal.core.builder.ClasspathMultiDirectory;
 import org.eclipse.wst.jsdt.internal.core.builder.NameEnvironment;
 import org.eclipse.wst.jsdt.internal.core.builder.SourceFile;
@@ -60,8 +61,9 @@
 			// Does not worth keep analyzing
 			parser.setSource(sf.getContents());
 			JavaScriptUnit unit = (JavaScriptUnit) parser.createAST(monitor);
-			
-			if(unit.getProblems().length > 0){
+			if(unit == null) {
+				Logger.log(Logger.ERROR, "AST couldn't be created during the validation of " + resource.getName());
+			} else if(unit.getProblems().length > 0){
 				CategorizedProblem[] resourceProblems = (CategorizedProblem[]) unit.getProblems();
 				for (CategorizedProblem problem : resourceProblems) {
 					ValidatorMessage vm = ValidatorMessage.create(problem.getMessage(), resource);
diff --git a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/validation/JSDTSourceValidator.java b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/validation/JSDTSourceValidator.java
index 335bbf5..19149f0 100644
--- a/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/validation/JSDTSourceValidator.java
+++ b/bundles/org.eclipse.wst.jsdt.ui/src/org/eclipse/wst/jsdt/internal/validation/JSDTSourceValidator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016 RedHat, Inc.
+ * Copyright (c) 2016, 2017 RedHat, Inc.
  * 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
@@ -224,7 +224,22 @@
 		parser.setSource(source);
 		parser.setProject(JavaScriptCore.create(file.getProject()));
 		JavaScriptUnit unit = (JavaScriptUnit) parser.createAST(new NullProgressMonitor());
-		if(unit.getProblems().length > 0){
+		if (unit == null) {
+			Message valMessage = new Message(JavaScriptUI.ID_PLUGIN, IMessage.HIGH_SEVERITY, JavaScriptUI.ID_PLUGIN + ".problem" ) { //$NON-NLS-1$
+				/**
+				 * @see IMessage#getText(Locale, ClassLoader)
+				 */
+				public java.lang.String getText(Locale locale, ClassLoader classLoader) {
+					return "AST couldn't be created due to the fatal error"; //$NON-NLS-1$
+				}
+
+			};
+			valMessage.setOffset(0);
+			valMessage.setLength(0);
+			valMessage.setLineNo(0);
+			reporter.addMessage(this, valMessage);
+			
+		} else if(unit.getProblems().length > 0){
 			for (IProblem problem : unit.getProblems()) {
 
 				final String msg = problem.getMessage();